OrientationChange不会破坏活动?

时间:2013-09-20 15:39:42

标签: java android

我在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()上的断点被调用了?鉴于此时对活动的引用已丢失,这不是很奇怪吗?

请让我深入了解这一点。

2 个答案:

答案 0 :(得分: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">

这会阻止活动在方向更改时重新启动,并且您不应该遇到任何问题(除了某些布局修复)

答案 1 :(得分:0)

Activty通过强引用引用了之前的AsyncTask

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

您可以尝试在服务中执行任务,并让前台中的任何活动接收广播,或者您可以尝试让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();
        }
    }
}