0

我在 Android 中有一个相当常见的情况,这与之前的 asynctask 更新活动有关,而活动由于方向改变而丢失。

我有一个活动,活动 A。

Activity A implements OnDownloadCompleteListener {

    public void  sync()
    {
        new SyncAttestationInfoTask(this).execute();
    }

    @Override
    public void onComplete() 
    {
        loadAttestationInfo();
    }
}

这是我的 asynctask 缩短:

package com.evento.mofa.backgroundtasks;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Ahmed
 *
 */
public class SyncAttestationInfoTask extends AsyncTask<Void, Void,Void> {

    /*TIP*/
    //TO SPEED UP THIS OPERATION WE CAN USE THE EXECUTEONEXECUTOR . 

    private ProgressDialog pd;
    private OnDownloadComplete parentActivityContext;   
    EntityConvert convert = new EntityConvert();
    private AttestationDao aDao = new AttestationDao();

    @Override
    protected Void doInBackground(Void... params) {
        // TODO Auto-generated method stub

        if (Locale.getDefault().getLanguage().equals("ar"))
        {
            /*EMPTY ALL THE TABLES THEN START PROCESSING*/
            aDao.flushTables(Locale.getDefault().getLanguage());
            syncAttestLocations(Webservices.ATTEST_LOCATION_AR,1);
            syncDocumentTypes(Webservices.DOCUMENT_TYPES_AR,1);
            syncAttestationInfo(Webservices.ATTESTATION_INFO_AR,1); 
        } else {
            /*EMPTY ALL THE TABLES THEN START PROCESSING*/
            aDao.flushTables(Locale.getDefault().getLanguage());
            syncAttestLocations(Webservices.ATTEST_LOCATION,0);
            syncDocumentTypes(Webservices.DOCUMENT_TYPES,0);
            syncAttestationInfo(Webservices.ATTESTATION_INFO,0);    
        }
        return null;
    }

    public SyncAttestationInfoTask(OnDownloadComplete context) {
        parentActivityContext = context;
    }

    @Override
    protected void onPreExecute() {
        pd = new ProgressDialog((Context)parentActivityContext);
        pd.setTitle("Loading...");
        pd.setMessage("Updating Data.");
        pd.setCancelable(false);
        pd.setIndeterminate(true);
        pd.show();
    }

    @Override
    protected void onPostExecute(Void result) {
        pd.dismiss();
        parentActivityContext.onComplete();
        // findViewById(R.id.the_button).setEnabled(true);
    }
}

我的活动有些奇怪。


  • 我在我的活动中的 onComplete 回调上放了一个断点
  • 我在同步异步任务中启动了一个进度对话框。
  • 一旦屏幕上显示进度对话框,我就会横向查看我的设备。
  • 对话框消失,并pd.dismiss()引发“未附加视图”错误(我知道它附加到的活动不再存在)。
  • 以上意味着也parentActivityContext().oncomplete应该抛出相同的错误,但事实并非如此。
  • 我评论了pd.Dismiss(),发现onComplete()调用了断点?鉴于此时对活动的引用已经丢失,这不是很奇怪吗?

请让我对此有所了解。

4

2 回答 2

1

我会这样做

将此行添加到您的 Manifest.xml 文件中,这将防止onCreate()屏幕旋转时调用。

<activity android:name=".yourActivity" android:configChanges="keyboardHidden|orientation">

Android 3.2以上版本,还需要添加“screenSize”:

<activity android:name=".yourActivity" android:configChanges="keyboardHidden|orientation|screenSize">

这将防止活动在方向更改时重新启动,并且您应该没有任何问题(除了一些布局修复)

于 2013-09-20T15:45:42.447 回答
0

前一个ActivtyAsyncTask通过强引用引用。

  • 使用 Activity 1 构造的 AsyncTask (parentActivityContex = Activity 1)
  • 活动 1“被破坏”,活动 2 进入前台
  • AsyncTask 完成,调用 parentActivityContext (Activity 1) onComplete
  • 活动 2 只是坐在那里无所事事
  • 活动 1 不再有指向它的活动引用,被收集

您可以尝试在 Service 中执行任务并让前台的任何 Activity 接收广播,或者您可以尝试让 AsyncTask 引用带有setRetainInstance(true). 下面是第二种情况的一个例子。请注意,您可能希望处理 AsyncTask 完成而 Fragment 从一个 Activity 分离但尚未附加到下一个 Activity 的情况

public class ExampleDownloadFragment extends Fragment {
    @Override
    public void onCreate(final Bundle savedInstanceState) {
        setRetainInstance(true);
        new SyncAttestationInfoTask(this).execute();
    }

    public void onComplete() {
        final Activity activity = getActivity();
        if (activity != null && activity instanceof A) {
            ((A) activity).onComplete();
        }
    }
}
于 2013-09-20T16:48:46.887 回答