0

I have an Activity that extends FragmentActivity

In first Fragment (HomePage that extends Fragment) I need to load data from web, so I use ASyncTask.
Now the problem: I don't need to check and load data everytime Fragment is created/attach
but just in first instance, then I want to save state and load again data only on next onCreate Activity (That I hope it means next open of app, but we know that it doesn't)

So.. Where Should I put my ASyntTask.execute()? OnCreate inside Fragment? OnCreateView inside Fragment? On Attach inside Fragment? or OnCreate of Activity, store data in Bundle and then pass them to my Fragment?

Or, maybe other solutions to this?

EDIT

Resolved!

So on my OnCreate [Fragment] I added a

 if(savedInstanceState != null) {

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

But I didn't setInstanceRetain(True) cause I need to pass always through onCreate();

Then on onCreateView() Method I added also a check

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

I also needed to make sure about save instance with a

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

At the end I had to make data (Custom Object) implemented Parcelable to make sure everythign works!

4

4 回答 4

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 );
    }
}
于 2013-07-24T16:10:17.203 回答
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
            }
        });
    }
}
于 2013-07-25T08:17:48.187 回答
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
于 2013-07-25T08:03:11.557 回答
0

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

公共静态int计数器= 0;

并在您的 onCreate 片段中执行以下操作:

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

counter++;
}

并且它永远不会再次执行(计数器永远不会再次为 0),直到您销毁您的活动。

于 2013-07-24T15:55:31.300 回答