附加AsyncTask的Android Fragment在Activity中提交后返回null

时间:2017-01-09 19:55:03

标签: android android-fragments android-asynctask

我尝试了解实现AsyncTask并将其附加到Fragment背后的基本设计模式。我遵循了许多教程并实现了代码(没有提供任何内容): 1)我的Fragment类包含AsyncTask:

public class MyFragment extends Fragment
{
    public interface TaskCallback
    {
        void onPreExecute();
        void onProgressUpdate(Integer... i);
        void onPostExecute();
    }
    private TaskCallback mCallback;
    private Task mTask;

    @Override
    public void onAttach(Activity activity)
    {
        super.onAttach(activity);
        mCallback = (TaskCallback) activity;
    }
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);

        mTask = new Task();
        mTask.execute();
    }

    private class Task extends AsyncTask<Void, Integer, Void>
    {
        @Override
        protected void onPreExecute()
        {
            mCallback.onPreExecute();
        }

        @Override
        protected Void doInBackground(Void... params)
        {
            for (int i=0; i<100; i++)
            {
                publishProgress(i*10);
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... values)
        {
            mCallback.onProgressUpdate(values);
        }

        @Override
        protected void onPostExecute(Void aVoid)
        {
            mCallback.onPostExecute();
        }
    }
}

2)我的主要活动代码

public class MainActivity extends ActionBarActivity implements MyFragment.TaskCallback
{
    private ProgressBar mProgress;
    private MyFragment mTaskFragment;
    private final static String TAG_FRAGMENT = "Fragment Task";

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mProgress = (ProgressBar) findViewById(R.id.progressBar1);
        mProgress.setProgress(0);

        //create fragment manager and fragment instance
        FragmentManager mFM = getSupportFragmentManager();
        mTaskFragment = (MyFragment) mFM.findFragmentByTag(TAG_FRAGMENT);

        if(mFM == null)
        {
           mTaskFragment = new MyFragment();
           mFM.beginTransaction().add(mTaskFragment, TAG_FRAGMENT).commit();
        }
//I added this method, but to no help, the same without this method
       mFM.executePendingTransactions();
    }


    @Override
    public void onPreExecute()
    {
        mProgress.setVisibility(View.VISIBLE);
    }

    @Override
    public void onProgressUpdate(Integer... i)
    {
        mProgress.setProgress(i[0]);
    }

    @Override
    public void onPostExecute()
    {
        mProgress.setVisibility(View.INVISIBLE);
    }
}

基本上,在

之后通过Debug运行代码时
mTaskFragment = (MyFragment) mFM.findFragmentByTag(TAG_FRAGMENT);
    if(mFM == null)
    {
       mTaskFragment = new MyFragment();
       mFM.beginTransaction().add(mTaskFragment, TAG_FRAGMENT).commit();
    } 

提供mTaskFragment = null

我想这是问题(mTaskFragment = null),代码不会创建MyFragment的实例。
问题:如何使用此(Fragment + AsyncTask)模式更改代码以从后台更新ProgressBar?
另一个问题:片段onAttached(Activity a)已被弃用,现在我们应该使用onAttached(Context context),是否意味着它应该像:mCallback = (TaskCallback) context;一样实现?

1 个答案:

答案 0 :(得分:0)

recur替换为if(mFM == null),以检查片段是否为空而不是FragmentManager。

还有更新的方法:

if(mTaskFragment == null)public void onAttach(Activity activity)

使用:public void onAttach(Context context)很好,因为mCallback = (TaskCallback) context;Context的超类(只需确保您的Activity正在实现界面)