Reputation: 411
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
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
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
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