1

MyObjectいくつかの乱数を設定するオブジェクト があります。それほど時間はかからず、一見瞬時に実行されます。ただし、これらの値は UI で使用され、UI の構築時に完全に準備ができていない場合があります。

AsyncTaskオブジェクトのインスタンス化に使用される を作成しました。これはこの投稿の最後にあります。

ただし、この方法で呼び出されるdoInBackground(...)前に、オブジェクトを完全にインスタンス化することはありません。onPostExecute(...)

protected MyObject doInBackground(Void... unused) {
    // this may take a few moments and cause a null reference
    // so make a task
    MyObject obj = new MyObject();
    return obj;
}

また、完了を示すためにフラグを使用しようとしましたが、どちらも保証されていないようです。

MyObject obj = new MyObject();
while (obj.isComplete() == false) {
    // do nothing. Wait for completion
}

return obj;

MyObjectはシンプル

public MyObject() {
    createValues(); // entire object created with this
    this.mComplete = true;
}

失敗は少なくなりますが、それでも失敗します。競合状態に寄与している場合、計算の一部に をcreateValues()使用します。ArrayList

MyFragment以下は、のタスクを使用する例ですmethodCall()

質問MyObjectが完全にインスタンス化されて終了するまで待つにはどうすればよいですか?

スタックトレース

java.lang.NullPointerException
    at MyFragment.setupFragment(MyFragment.java:95)
    at MyFragment.onTaskComplete(MyFragment.java:143)
    at MyTask.onPostExecute(MyTask.java:37)
    at MyTask.onPostExecute(MyTask.java:1)
    at android.os.AsyncTask.finish(AsyncTask.java:631)

断片

public class MyFragment extends Fragment implements MyTask.OnTaskComplete {
    private MyObject mMyObject;

    // ...

    public void methodCall() {
        // generate puzzle and set it up in the background
        MyTask task = new MyTask(this);
        task.execute();
    }

    function void setupFragment() {
            // null pointer exception here
            // mMyObject is not initiated yet and only some times
            // values is an array of integers
        int example = this.mMyObject.values[0];
    }

    @Override
    public void onTaskComplete(MyObject obj) {
        // returned from MyTask
        this.mMyObject = obj;
        this.setupFragment(); 
    }
}

非同期タスク

public class MyObjectTask extends AsyncTask<Void, Void, MyObject> {
    public static interface OnTaskComplete {
        public abstract void onTaskComplete(MyObject obj);
    }
    static final String TAG = "MyObjectTask";

    private OnTaskComplete mListener;

    public MyObjectTask(OnTaskComplete listener) {
        this.mListener = listener;
    }

    @Override
    protected MyObject doInBackground(Void... unused) {
        // this may take a few moments and cause a null reference
        // so make a task
        return new MyObject();
    }

    @Override
    protected void onPostExecute(MyObject obj) {
        this.mListener.onTaskComplete(obj);
    }
}
4

2 に答える 2

1

AsyncTaskからonPreExecuteメソッドでオブジェクトを作成できます。したがって、doInBackgroundが呼び出されたとき、オブジェクトはすでに作成されています。その時点で、メソッドを呼び出して値を作成できます

public class MyObjectTask extends AsyncTask<Void, Void, MyObject> {
    public static interface OnTaskComplete {
        public abstract void onTaskComplete(MyObject obj);
    }

    static final String TAG = "MyObjectTask";

    private OnTaskComplete mListener;
    private MyObject myObject;

    public MyObjectTask(OnTaskComplete listener) {
        this.mListener = listener;
    }

    @Override
    protected void onPreExecute() {
        myObject = new MyObject();
    }

    @Override
    protected MyObject doInBackground(Void... unused) {
         // this may take a few moments and cause a null reference
        // so make a task
        myObject.createValues();
       return myObject;
    }

    @Override
    protected void onPostExecute(MyObject obj) {
        this.mListener.onTaskComplete(obj);
    }
}
于 2013-02-17T05:48:11.607 に答える
1

オブジェクトを作成するときにオブジェクト内に新しいスレッドを作成していなければ、あなたがしていることは完全にうまくいくはずです。

タスクを実行する前に最初に設定する必要があるコールバックを追加しました。その後、AsyncTask が終了したときにトリガーされます (doInBackground が終了し、post execute が呼び出されます)。

したがって、コードで見ていることから、コンストラクターが終了せず、オブジェクトがコールバックで返されることはありません。

そのため、メソッド createValues でオブジェクトに例外がスローされる可能性があるかどうかを確認してください。

発生した例外のスタックトレースはありますか?

于 2013-02-17T03:05:51.217 に答える