ASyncTask仅在第一次打开时

时间:2013-07-24 15:50:30

标签: android android-fragments android-asynctask oncreate

我有一个扩展FragmentActivity的活动

在第一个Fragment(扩展Fragment的主页)中我需要从web加载数据,所以我使用ASyncTask。
现在的问题是:我不需要每次创建/附加片段时检查和加载数据但只是在第一个实例中,然后我想保存状态并仅在下一个onCreate Activity上再次加载数据(我希望它意味着下次打开应用程序,但我们知道它没有)

那么..我应该把ASyntTask.exe()放在哪里?片段内的OnCreate?片段内的OnCreateView?在片段内附加?或OnCreate of Activity,将数据存储在Bundle中,然后将它们传递给我的Fragment?

或者,可能还有其他解决方案吗?

修改

解决!

所以在我的OnCreate [片段]上我添加了一个

 if(savedInstanceState != null) {

        data = (data[]) savedInstanceState.getParcelableArray("key");
    }
    else
        new LoadMostBooks().execute();

但是我没有setInstanceRetain(True)因为我需要总是通过onCreate();

然后在onCreateView()方法上我添加了一个检查

if(savedInstanceState != null) {
        myCustomArrayAdapter = new CustomArrayArrayAdapter(mContext,data);
        myListView.setAdapter(myCustomArrayAdapter);
    }

我还需要确保使用

保存实例
 @Override
public void onSaveInstanceState( Bundle outState ) {
    super.onSaveInstanceState( outState );
    outState.putParcelableArray("key",data);
}

最后我不得不使数据(自定义对象)实现Parcelable以确保每个标志都有效!

4 个答案:

答案 0 :(得分:2)

您可以保留您的数据onSaveInstanceState,然后检查onCreate是否存在。

private Data[] mData;

@Override
public void onCreate( Bundle savedInstanceState ) {

    super.onCreate( savedInstanceState );
    setRetainInstance( true );
    if ( savedInstanceState != null && savedInstanceState.containsKey( "key" ) ) {

        mData = (Data[]) savedInstanceState.getParcelableArray( "key" );
    }
    else {
        new myAsync() {

            @Override
            public void onPostExecute( Data[] data ) {

                mData = data;
            }
        }.execute();
    }
}

@Override
public void onSaveInstanceState( Bundle outState ) {

    super.onSaveInstanceState( outState );
    if ( mData != null ) {

        outState.putParcelableArray( "key", mData );
    }
}

答案 1 :(得分:0)

您可以做的是在第一个活动中创建一个静态字段。

public static int counter = 0;

并在你的onCreate片段中执行:

if (counter == 0){
//execute Async

counter++;
}

并且在你破坏你的活动之前它永远不会再次执行(计数器永远不会再为0)。

答案 2 :(得分:0)

你唯一需要做的就是:检查数据加载与否,如果已加载,则无需重新加载,如果不加载数据则。

通过提供私有构造函数将您的Fragment设为singleInstance:

  public static YourFragment mInstance;
         private YourFrament(){//empty constructor
          super();
         }
         public static YourFragment getInstance(){
          if(mInstance==null){
           mInstance = new YourFrament();
         }
          return mInstance;
         }

声明您的数据持有者

private List<DataType> mDatas;

假设您在onActivityCreated中调用AsyncTask:  首先检查您的数据:

if(mDatas==null||mData.size<=0){
//here you need to get data by call your AsyncTask
yourAsyncTask = new AsyncTask...
yourAsyncTask.execute()
}else{
//here you have the data already, no need to load
}

和你的AsyncTask的onPostExecute()方法:

 mDatas = new ArrayList<DataType>();
 mDatas=....// init your data value

答案 3 :(得分:0)

您可以让活动类提供数据(懒惰):

private Object data;

public static interface Callback{
    public void onData(Object data);
}

public void getData(final Callback c){

  if(data != null){
    c.onData(data);
  }else {

      AsyncTask<Void,Void,Object> task = new AsyncTask<Void, Void, Object>() {
          @Override
          protected Object doInBackground(Void... pVoids) {
              //--load data--
              return new Object();
          }

          @Override
          protected void onPostExecute(Object result) {
              super.onPostExecute(result);
              data = result;
              c.onData(data);
          }
      }.execute();

  }

}

并在片段类中询问数据:

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    if(getActivity() instanceof MyActivity){
        ((MyActivity) getActivity()).getData(new MyActivity.Callback() {
            @Override
            public void onData(Object data) {
                //--do something with the data in fragment
            }
        });
    }
}