0

My app needs to get data from the server. So I show ProgressDialog in onPreExecute() method and in the doInBackground() method the data is loaded from the server.

At this moment if I change the orientation, the app force closes. Because the current activity is destroyed and the doInBackground() might still refer the old activity. So, I have referred this post which discusses the same issue. But I don't want to use android:configchanges as it is not preferred. androiddevelopersite says this should be the last resort and not preferred for the most applications.

So, can someone please suggest with necessary code snippets on how to handle the situation in such a way that my app doesn't force close?

Eidt: My code

    public class DataListActivity extends BaseActivity {

        private ArrayList<String> valueslist;

        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.listlayout);
                     new LoadAsync().execute();

        }


         class LoadAsync extends AsyncTask<String, String, String> {

                /**
                 * Before starting background thread Show Progress Dialog
                 * */
                @Override
                protected void onPreExecute() {
                    super.onPreExecute();
                    progressDialog = new ProgressDialog(DataListActivity.this);
                    progressDialog.setMessage("Loading...");
                    progressDialog.setIndeterminate(false);
                    progressDialog.setCancelable(false);
                    progressDialog.show();
                }

                /**
                 * getting All datafrom url
                 * */
                protected String doInBackground(String... args) {

                    //Here I am doing httppost request.
                           try{ 
                            // looping through All data that I got from the server
                            for (int i = 0; i < subCategoriesJson.length(); i++) {
                                JSONObject jsonobj = subCategoriesJson.getJSONObject(i);

                                // Storing each json item in variable
                                String item = jsonobj.getString("data");

                                valueslist.add(item);

                            }
                            return "1";
                        }                    
                        else {

                            return null;
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }   
                    return null;
                }

   protected void onPostExecute(String msg) {

                    if( msg != null && msg.equals("1"))
                    {

                     progressDialog.dismiss();

                     runOnUiThread(new Runnable() {

                         public void run() {
                             //Updating parsed json data to Listview

                            ListView listView = (ListView)findViewById(R.id.list1);

            ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getApplicationContext(),R.layout.list_item, valueslist);
                                listView.setAdapter(arrayAdapter); 

          listView.setOnItemClickListener(new OnItemClickListener() {

            @Override
                            public void onItemClick(AdapterView<?> parent, View view,
                                            int position, long id) {


                                 String selectedthing = valueslist.get(position);

                                    }
                                }); 

                         }
                     });
                }else 
                {
                          //There is no data.
                }

                }

         }

    }

Note: I am providing this information though it isn't necessary for this question. My activity has two layout files. One is for portrait and other is for landscape mode in layout-land folder.

Below is the logcat window:

02-27 19:54:40.294: E/WindowManager(11710): Activity com.example.DataList has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40555388 that was originally added here
02-27 19:54:40.294: E/WindowManager(11710): android.view.WindowLeaked: Activity com.example.prog.DataList has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40555388 that was originally added here
02-27 19:54:40.294: E/WindowManager(11710):     at android.view.ViewRoot.<init>(ViewRoot.java:277)
02-27 19:54:40.294: E/WindowManager(11710):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
02-27 19:54:40.294: E/WindowManager(11710):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
02-27 19:54:40.294: E/WindowManager(11710):     at android.view.Window$LocalWindowManager.addView(Window.java:433)
02-27 19:54:40.294: E/WindowManager(11710):     at android.app.Dialog.show(Dialog.java:265)
02-27 19:54:40.294: E/WindowManager(11710):     at com.example.prog.DataList$LoadAsync.onPreExecute(DataList.java:77)
02-27 19:54:40.294: E/WindowManager(11710):     at android.os.AsyncTask.execute(AsyncTask.java:391)
02-27 19:54:40.294: E/WindowManager(11710):     at com.example.prog.DataList.onCreate(DataList.java:52)
02-27 19:54:40.294: E/WindowManager(11710):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1072)
02-27 19:54:40.294: E/WindowManager(11710):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1794)
02-27 19:54:40.294: E/WindowManager(11710):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1851)
02-27 19:54:40.294: E/WindowManager(11710):     at android.app.ActivityThread.access$1500(ActivityThread.java:132)
02-27 19:54:40.294: E/WindowManager(11710):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1038)
02-27 19:54:40.294: E/WindowManager(11710):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-27 19:54:40.294: E/WindowManager(11710):     at android.os.Looper.loop(Looper.java:150)
02-27 19:54:40.294: E/WindowManager(11710):     at android.app.ActivityThread.main(ActivityThread.java:4277)
02-27 19:54:40.294: E/WindowManager(11710):     at java.lang.reflect.Method.invokeNative(Native Method)
02-27 19:54:40.294: E/WindowManager(11710):     at java.lang.reflect.Method.invoke(Method.java:507)
02-27 19:54:40.294: E/WindowManager(11710):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
02-27 19:54:40.294: E/WindowManager(11710):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
02-27 19:54:40.294: E/WindowManager(11710):     at dalvik.system.NativeStart.main(Native Method)
02-27 19:54:40.294: E/ResourceType(11710): Style contains key with bad entry: 0x010102f3
02-27 19:54:40.294: E/ResourceType(11710): Style contains key with bad entry: 0x01010300
02-27 19:54:40.294: E/ResourceType(11710): Style contains key with bad entry: 0x0101039c
Community
  • 1
  • 1
Apparatus
  • 411
  • 1
  • 5
  • 19
  • post all logcat data...then we can understand what is the problem or what exceptions were thrown when force close occured. – Ajit Feb 27 '13 at 12:44
  • some code might be useful aswell. coz when i have an active ProgressDialog, i can switch orientation without any trouble. – bofredo Feb 27 '13 at 12:50

3 Answers3

2

You must dismiss your dialog in onPause() and, if required, show it again in onResume().

You might want to retain some state about the dialog between the instances of your Activity using onRetainNonConfigurationInstance() and retrieve it from the Bundle passed to onCreate().

Simon
  • 14,407
  • 8
  • 46
  • 61
1

You can disable orientation changes while waiting for data from server. You can set your orientation portrait for a moment:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

For more, clear explanations visit: How do I disable orientation change on Android?

Community
  • 1
  • 1
buttib
  • 113
  • 3
  • 12
  • I didn't want to restrict orientation change even at the runtime for that moment.Moreover what if the user starts from landscape and then changed to portrait? – Apparatus Feb 27 '13 at 13:23
  • @Sam I suppose that users usually open an apk in portrait mode but you are right. But also you can force user to start activity in portrait mode before start downloading data from server. If you set the orientation before your duty, user can not change it to landscape until you let him again. And also, if you want, you can check the orientation then set it landscape or portrait. Please check visit: http://stackoverflow.com/questions/4697631/android-screen-orientation – buttib Feb 27 '13 at 13:43
  • It is a hack, and one with a lot of side effects. Far too many devs disable orientations changes as a quick fix to avoid having to learn, and code for, the Activity lifecycle. Without this, you become vulnerable to all of the other things that can destroy and recreate your Activity other than orientation changes. – Simon Feb 27 '13 at 14:13
0

This is the same answer as Simon gave you, but with a code example. You must check if the progress is complete, otherwise the progressbar will show get stuck at 100%.

@Override
public void onPause() {
    super.onPause();  // Always call the superclass method first

    proDialog.dismiss();
}

@Override
public void onResume(){
    super.onResume();


    proDialog.show();
}
johgru
  • 241
  • 2
  • 5
  • 20