Changing the handle orientation when starting AsyncTask

Use Case:

The user will launch an application that will download captcha. The user will fill in captcha and try to download some information.

Problem:

If the user rotates the device while the Activity loading, it is destroyed. At the end of execution, AsyncTask tries to update the destroyed Activity , and the result - "not connected to the window manager.

Invalid solution:

I can mask the problem with android:configChanges="orientation|keyboardHidden|screenSize" , but with this the layout will not be updated to the landscape.

What am I asking:

Is it possible to change the orientation and change the "link" of the Context passed to AsyncTask ?

This answer suggests checking if the dialog is not null, but that is not what I am looking for.

Here he suggests using WeakReference ( here is a good snippet on how to use it), but I did not understand that this is what I am looking for.

To be more explicit, this is what I do in onPostExecute:

 @Override protected void onPostExecute(Auto result) { progress.dismiss(); new DownloaderCaptcha(context).execute(""); ((EditText)context.findViewById(R.id.editTextCaptcha)).setText(""); context.findViewById(R.id.progrBar).setVisibility(View.VISIBLE); context.findViewById(R.id.captcha).setVisibility(View.INVISIBLE); if(result != null) { Storage.storeHistory(context, result.getTarga().getValue()); Intent i = new Intent(context, MenuActivity.class); i.putExtra("result", result); context.startActivity(i); } else { ErrorDialog.show(context, error); } } 
+7
source share
2 answers

Here are my tips:

  • Use non android:configChanges to solve this problem.

  • Use not Activity#onRetainNonConfigurationInstance() to eliminate it (since this approach is deprecated).

  • Use a saved working Fragment instead. I recently published an article describing how to handle configuration changes using saved Fragment s. This solves the problem of keeping AsyncTask by changing rotation beautifully. You need to place the AsyncTask inside the Fragment , call setRetainInstance(true) on the Fragment and report the progress of the AsyncTask to it Activity through the saved Fragment .

+15
source

Wrong solution:

I can hide the problem using android: configChanges = "orientation | keyboardHidden | screenSize", but with this the layout will not be updated to the landscape.

Actually it will be.

android: configChanges Displays configuration changes that make will process itself. When a configuration change occurs at run time, activity is disabled and restarted by default, but a configuration declaration with this attribute will prevent restarting. Instead, the activity continues to work and its onConfigurationChanged () method is called.

Take a look at http://developer.android.com/guide/topics/manifest/activity-element.html#config

You can implement a layout for the Landscape and Portrait modes, or to undo an AsyncTask change when you change the configuration.

0
source

All Articles