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);
}
}