Apparatus
Apparatus

Reputation: 411

how to avoid force close when orientation is changed

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

Upvotes: 0

Views: 1066

Answers (3)

johgru
johgru

Reputation: 241

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();
}

Upvotes: 0

Simon
Simon

Reputation: 14472

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().

Upvotes: 2

buttib
buttib

Reputation: 113

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?

Upvotes: 1

Related Questions