I have activity A and B. Both of them have AsyncTasks that connect to the web and fetch some JSON. I get an error that I can't quite replicate always, but I'm not sure what I'm doing wrong. I get the error when I press the back button from activity B to A to Homescreen.
protected Void doInBackground(Void... params) {
synchronized (this) {
if (img_flag == 1) {
System.out.println("entered into doinback1");
UploadImage();
System.out.println("entered into doinback2");
}
if (offlineast_flag == 0) {
System.out.println("entered into doinback3");
UpdateAsset_webService();
System.out.println("entered into doinback4");
ServiceRequest _autoupdate = new ServiceRequest();
_autoupdate.cat_sync(Update_asset.this, _companyId, _usrid,
access_id, profile_id, catid_db);
System.out.println("entered into doinback5");
}
if (img_flag == 2) {
System.out.println("entered into doinback6");
UploadImageOffline();
} else {
System.out.println("entered into doinback7");
loading_dialog.dismiss();
System.out.println("entered into doinback8");
}
}
return null;
}
// Update the progress
protected void onProgressUpdate(Integer... values) {
}
// after executing the code in the thread
protected void onPostExecute(Void result) {
onback();
loading_dialog.dismiss();
img_flag = 0;
Toast.makeText(getApplicationContext(),
"Your asset updated successfully.", Toast.LENGTH_LONG)
.show();
}
This is my Logcat:
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.Futuenter code herereTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.NullPointerException
at com.kodology.assetbin.Update_asset.UpdateAsset_webService(Update_asset.java:1733)
at com.kodology.assetbin.Update_asset$LoadViewTask.doInBackground(Update_asset.java:2239)
at com.kodology.assetbin.Update_asset$LoadViewTask.doInBackground(Update_asset.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
... 4 more
Related
I already have seen this question. But couldn't figure out what's the issue.
I am sending an email in background using BackgroundMail in my ImageSyncReciever class. But when email is sent my app crashes while giving me the below error
FATAL EXCEPTION: main
Process: com.thumbsol.accuratemobileassetsmanagament, PID: 7480
java.lang.IllegalArgumentException: View=com.android.internal.policy.impl.PhoneWindow$DecorView{300e55de V.E..... R.....I. 0,0-0,0} not attached to window manager
at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:434)
at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:353)
at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:116)
at android.app.Dialog.dismissDialog(Dialog.java:382)
at android.app.Dialog.dismiss(Dialog.java:365)
at com.creativityapps.gmailbackgroundlibrary.BackgroundMail$SendEmailTask.onPostExecute(BackgroundMail.java:302)
at com.creativityapps.gmailbackgroundlibrary.BackgroundMail$SendEmailTask.onPostExecute(BackgroundMail.java:265)
at android.os.AsyncTask.finish(AsyncTask.java:636)
at android.os.AsyncTask.access$500(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:653)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5660)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:963)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:758)
Below is my code in which I am sending the email
if (response.body().getStatus().equals("OK")) {
snapManager.updateSnapStatus(AssetsManagementContract.SnapEntry.COLUMN_SITE_SNAP, snap.getSnapName(), Constants.SNAP_SYNCED);
Intent broadcastSyc = new Intent();
broadcastSyc.setAction(Common.GetSyncImageAction());
broadcastSyc.putExtra("STATUS", true);
mContext.sendBroadcast(broadcastSyc);
sendImage(mContext);
BackgroundMail.newBuilder(mContext)
.withUsername("gmail id")
.withPassword("pass")
.withMailto("gmail id")
.withType(BackgroundMail.TYPE_PLAIN)
.withSubject("New Meter Installation")
.withBody("Meter #" + msn + " is "+ com+ " and "+ status)
.send();
}
How can i resolve this issue? Any help would be highly appreciated
Note: The email is sent when the form is submitted and after saving I am not using any dialog.
Update 1
Below is the BackgroudMailer class function
public class SendEmailTask extends AsyncTask<String, Void, Boolean> {
private ProgressDialog progressDialog;
public SendEmailTask() { //error onPostExecute(BackgroundMail.java:265)
}
protected void onPreExecute() {
super.onPreExecute();
if(BackgroundMail.this.processVisibility) {
this.progressDialog = new ProgressDialog(BackgroundMail.this.mContext);
this.progressDialog.setMessage(BackgroundMail.this.sendingMessage);
this.progressDialog.setCancelable(false);
this.progressDialog.show();
}
}
protected Boolean doInBackground(String... arg0) {
try {
GmailSender sender = new GmailSender(BackgroundMail.this.username, BackgroundMail.this.password);
if(!BackgroundMail.this.attachments.isEmpty()) {
for(int i = 0; i < BackgroundMail.this.attachments.size(); ++i) {
if(!((String)BackgroundMail.this.attachments.get(i)).isEmpty()) {
sender.addAttachment((String)BackgroundMail.this.attachments.get(i));
}
}
}
sender.sendMail(BackgroundMail.this.subject, BackgroundMail.this.body, BackgroundMail.this.username, BackgroundMail.this.mailto, BackgroundMail.this.type);
} catch (Exception var4) {
var4.printStackTrace();
return Boolean.valueOf(false);
}
return Boolean.valueOf(true);
}
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if(BackgroundMail.this.processVisibility) {
this.progressDialog.dismiss(); // error onPostExecute(BackgroundMail.java:302)
if(result.booleanValue()) {
if(!TextUtils.isEmpty(BackgroundMail.this.sendingMessageSuccess)) {
Toast.makeText(BackgroundMail.this.mContext, BackgroundMail.this.sendingMessageSuccess, 0).show();
}
if(BackgroundMail.this.onSuccessCallback != null) {
BackgroundMail.this.onSuccessCallback.onSuccess();
}
} else {
if(!TextUtils.isEmpty(BackgroundMail.this.sendingMessageError)) {
Toast.makeText(BackgroundMail.this.mContext, BackgroundMail.this.sendingMessageError, 0).show();
}
if(BackgroundMail.this.onFailCallback != null) {
BackgroundMail.this.onFailCallback.onFail();
}
}
}
}
}
The problem is I cannot edit it as the file is locked.
in onPostExecute you dismiss the dialog without checking if it is actually shown:
this.progressDialog.dismiss();
add a check of isShowing for that (and a null-check just in case..)
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
Also I see that you use static references to contexts. That can lead to memory leaks, but that is just a side note.
I have an app that downloads the current unix timestamp from the internet. The code for the download task is as follows.
public class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String result = "";
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL(urls[0]);
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while (data != -1) {
char current = (char) data;
result += current;
data = reader.read();
}
return result;
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(SplashActivity.this, "you aint got no internet man", Toast.LENGTH_SHORT).show();
}
return null;
}
I run this code in onCreate
DownloadTask task = new DownloadTask();
String result = null;
try {
result = task.execute("http://www.currenttimestamp.com/").get();
Pattern p = Pattern.compile("current_time = (.*?);");
Matcher m = p.matcher(result);
m.find();
String unixTime = (m.group(1));
timeStamp = Integer.parseInt(unixTime);
endTimeMaths = endTime/1000;
} catch (InterruptedException e) {
e.printStackTrace();
Toast.makeText(SplashActivity.this, "you aint got no internet man", Toast.LENGTH_SHORT).show();
} catch (ExecutionException e) {
e.printStackTrace();
Toast.makeText(SplashActivity.this, "you aint got no internet man", Toast.LENGTH_SHORT).show();
}
timeDelta = timeStamp-endTimeMaths;
Log.i("TimeDelta", timeDelta+"");
//If dem boys cheatin
if (timeDelta < 1){
Toast.makeText(SplashActivity.this, "You cheatin boi?", Toast.LENGTH_SHORT).show();
reward=false;
} else if (timeDelta >= 300){
reward = true;
Toast.makeText(SplashActivity.this, "Here is your reward for being gone", Toast.LENGTH_SHORT).show();
}
}
The Exception is as follows
09-04 21:26:42.853 8459-8493/com.firefluxentertainment.retroclicker E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.firefluxentertainment.retroclicker, PID: 8459
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:318)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.widget.Toast$TN.<init>(Toast.java:346)
at android.widget.Toast.<init>(Toast.java:101)
at android.widget.Toast.makeText(Toast.java:260)
at com.firefluxentertainment.retroclicker.SplashActivity$DownloadTask.doInBackground(SplashActivity.java:155)
at com.firefluxentertainment.retroclicker.SplashActivity$DownloadTask.doInBackground(SplashActivity.java:119)
at android.os.AsyncTask$2.call(AsyncTask.java:304)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Since all the code is in try catch braces I have no idea why it would be crashing. Any help is very much appreciated!
This is because you are trying to show toast in a non-UI thread. There are multiple solutions to your problem :
Create a handler in the Activity and pass it along to DownloadTask. Simply send a message in Handler and show the toast.
Another solution is to send the context in DownloadTask and show the toast as
context.runOnUIThread(new Runnable() {
public void run(){
Toast.showToast("your message here")
}
)
You can send the result of your task in onPostExecute() and show Toast there.
Below is my code using inner class Fragment. Also I am using an AsyncTask to perform some background operation. It throws a Fatal Exception while executing.
public class LocationFragment extends Fragment {
// Progress Dialog
private ProgressDialog pDialog;
// JSON parser class
JSONParser jsonParser = new JSONParser();
//gps class
GPSTracker gps;
double latitude,longitude;
public TextView current_location;
private static final String BC_URL = "http://manfredinfotech.com/projects/workshop/get_location.php";
//JSON element ids from repsonse of php script:
private static final String TAG_SUCCESS = "success";
private static final String TAG_MESSAGE = "message";
public LocationFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// create class object
gps = new GPSTracker(getActivity());
// check if GPS enabled
View rootView = inflater.inflate(R.layout.fragment_location, container, false);
current_location = (TextView) rootView.findViewById(R.id.current_location);
if (gps.canGetLocation()) {
latitude = gps.getLatitude();
longitude = gps.getLongitude();
// \n is for new line
Toast.makeText(getActivity(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();
new GetLocation().execute();
}
return rootView;
}
class GetLocation extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute(){
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Processing...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(String... args){
int success;
try{
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("lat",String.valueOf(latitude)));
params.add(new BasicNameValuePair("lon", String.valueOf(longitude)));
JSONObject json = jsonParser.makeHttpRequest(BC_URL, "POST", params);
System.out.println("JSON" + json);
// check your log for json response
Log.d("Here", json.toString());
success = json.getInt(TAG_SUCCESS);
if(success == 1){
if(pDialog.isShowing())pDialog.dismiss();
System.out.println(json.getString(TAG_MESSAGE));
current_location.setText(json.getString(TAG_MESSAGE));
//return json.getString(TAG_MESSAGE);
} else {
if(pDialog.isShowing())pDialog.dismiss();
current_location.setText("Not location found");
System.out.println("Failed!");
//return json.getString(TAG_MESSAGE);
}
}
catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}
}
Now this line current_location.setText(json.getString(TAG_MESSAGE));
throws error. Below is the Stacktrace for the exception I am getting.
> 08-20 12:30:44.242 27109-27190/com.mipl.trupco E/AndroidRuntime﹕
> FATAL EXCEPTION: AsyncTask #1
> Process: com.mipl.trupco, PID: 27109
> java.lang.RuntimeException: An error occured while executing doInBackground()
> at android.os.AsyncTask$3.done(AsyncTask.java:304)
> at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
> at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
> at java.util.concurrent.FutureTask.run(FutureTask.java:242)
> at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
> at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
> at java.lang.Thread.run(Thread.java:818)
> Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the
> original thread that created a view hierarchy can touch its views.
> at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6357)
> at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:874)
> at android.view.View.requestLayout(View.java:17476)
> at android.view.View.requestLayout(View.java:17476)
> at android.view.View.requestLayout(View.java:17476)
> at android.view.View.requestLayout(View.java:17476)
> at android.support.v4.widget.DrawerLayout.requestLayout(DrawerLayout.java:749)
> at android.view.View.requestLayout(View.java:17476)
> at android.view.View.requestLayout(View.java:17476)
> at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:360)
> at android.view.View.requestLayout(View.java:17476)
> at android.widget.TextView.checkForRelayout(TextView.java:6871)
> at android.widget.TextView.setText(TextView.java:4057)
> at android.widget.TextView.setText(TextView.java:3915)
> at android.widget.TextView.setText(TextView.java:3890)
> at com.mipl.trupco.LocationFragment$GetLocation.doInBackground(LocationFragment.java:99)
> at com.mipl.trupco.LocationFragment$GetLocation.doInBackground(LocationFragment.java:65)
> at android.os.AsyncTask$2.call(AsyncTask.java:292)
> at java.util.concurrent.FutureTask.run(FutureTask.java:237)
> at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
> at
Please help
You have to move the portion of the background task that updates the ui on to the main thread. There is a simple piece of code for this:
runOnUiThread(new Runnable() {
#Override
public void run() {
//Update your UI
}
});
Activity.runOnUiThread
Or you can write the code in onPostExecute of Asynctask.
You are manipulating your layout, i.e. your current_location textview from background thread (doInBackground). This is not allowed, the error states this out. For manipulating view elements you should use onPreExecute or onPostExecute methods.
The error is in your doInBackground() whenever success == 1 or not because you try to edit the textview current_location from a thread.
So simple solution is to override onPostExecute() method inside your GetLocation class, return the text that you want to it and there you can set it. edit this inside the doInBackground()
if(success == 1){
if(pDialog.isShowing())pDialog.dismiss();
System.out.println(json.getString(TAG_MESSAGE));
return json.getString(TAG_MESSAGE);
} else {
if(pDialog.isShowing())pDialog.dismiss();
System.out.println("Failed!");
return "Not location found";
}
and add this new method to after doInBackground()
#Override
protected void onPostExecute(String result) {
if(result != null)
current_location.setText(result);
}
Logcat error message.
I receive this error when I attempt to register an account on the application, the app crashes momentarily and returns to the login page.
02-14 13:11:19.857 31983-31983/example.com.androidim E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: example.com.androidim, PID: 31983
java.lang.NullPointerException
at example.com.androidim.SignUp$2$1$1.run(SignUp.java:126)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:606
at dalvik.system.NativeStart.main(Native Method)
The following is line 111-142 in the SignUp activity.
if (passwordText.getText().toString().equals(passwordAgainText.getText().toString())){
if (usernameText.length() >= 5 && passwordText.length() >= 5) {
Thread thread = new Thread(){
String result = new String();
#Override
public void run() {
result = imService.signUpUser(usernameText.getText().toString(),
passwordText.getText().toString(),
eMailText.getText().toString());
handler.post(new Runnable(){
public void run() {
if (result.equals(SERVER_RES_RES_SIGN_UP_SUCCESFULL)) {
Toast.makeText(getApplicationContext(),R.string.signup_successfull, Toast.LENGTH_LONG).show();
showDialog(SIGN_UP_SUCCESSFULL);
}
else if (result.equals(SERVER_RES_SIGN_UP_USERNAME_CRASHED)){
Toast.makeText(getApplicationContext(),R.string.signup_username_crashed, Toast.LENGTH_LONG).show();
showDialog(SIGN_UP_USERNAME_CRASHED);
}
else //if (result.equals(SERVER_RES_SIGN_UP_FAILED))
{
Toast.makeText(getApplicationContext(),R.string.signup_failed, Toast.LENGTH_LONG).show();
showDialog(SIGN_UP_FAILED);
}
}
});
}
When calling equals on your result variable, result is null. You have to do a null-check before calling equals.
public void run() {
if(result != null){
if (result.equals(SERVER_RES_RES_SIGN_UP_SUCCESFULL)) {
Toast.makeText(getApplicationContext(),R.string.signup_successfull, Toast.LENGTH_LONG).show();
showDialog(SIGN_UP_SUCCESSFULL);
}
else if (result.equals(SERVER_RES_SIGN_UP_USERNAME_CRASHED)){
Toast.makeText(getApplicationContext(),R.string.signup_username_crashed, Toast.LENGTH_LONG).show();
showDialog(SIGN_UP_USERNAME_CRASHED);
}
else //if (result.equals(SERVER_RES_SIGN_UP_FAILED))
{
Toast.makeText(getApplicationContext(),R.string.signup_failed, Toast.LENGTH_LONG).show();
showDialog(SIGN_UP_FAILED);
}else{
//result == null
}
}
}
I have an activity that is displayed in portrait only and in my tablet it causes the following:
android.view.WindowLeaked: Activity com.spicycurryman.getdisciplined10.app.InstalledAppActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{53210b88 V.E..... R.....ID 0,0-1520,192} that was originally added here
at android.view.ViewRootImpl.<init>(ViewRootImpl.java:354)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:216)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
at android.app.Dialog.show(Dialog.java:281)
at com.spicycurryman.getdisciplined10.app.InstalledAppActivity$LoadApplications.onPreExecute(InstalledAppActivity.java:306)
at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
at android.os.AsyncTask.execute(AsyncTask.java:534)
at com.spicycurryman.getdisciplined10.app.InstalledAppActivity.onCreate(InstalledAppActivity.java:105)
at android.app.Activity.performCreate(Activity.java:5104)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
I am using an AsyncTask to load a listview of installed apps on the phone and using a progressdialog.
I have researched this problem:
Progress dialog and AsyncTask error
android.view.WindowLeaked exception
Android Error: Window Leaked in AsyncTask
I was able to produce this code so that the whole app doesn't crash and burn, but the exception is still thrown and the activity screen is kind of shaky after the button click and the whole transition is not really smooth.
#Override
protected void onPostExecute(Void result) {
apkList.setAdapter(new ApkAdapter(InstalledAppActivity.this, packageList1, packageManager));
try {
if ((this.pDialog != null) && this.pDialog.isShowing()) {
this.pDialog.dismiss();
}
} catch (final IllegalArgumentException e) {
// Handle or log or ignore
} catch (final Exception e) {
// Handle or log or ignore
} finally {
this.pDialog = null;
}
super.onPostExecute(result);
}
Dismissing the progress dialog or calling finish() doesn't really solve the problem either...
How would I fix this?
Here is most of the AsyncTask code:
private class LoadApplications extends AsyncTask<Void, Void, Void> {
private ProgressDialog pDialog;
List<PackageInfo> packageList1 = new ArrayList<PackageInfo>();
public LoadApplications(Context context){
Context mContext = context;
}
#Override
protected Void doInBackground(Void... params) {
List<PackageInfo> packageList = packageManager
.getInstalledPackages(PackageManager.GET_PERMISSIONS);
List<PackageInfo> packageList2 = packageManager
.getInstalledPackages(PackageManager.GET_PERMISSIONS);
for(PackageInfo pi : packageList) {
boolean b = isSystemPackage(pi);
boolean c = isSystemPackage1(pi);
boolean d = isSystemPackage2(pi);
if ((!b || !c ) && d ){
packageList1.add(pi);
}
}
//here you got email and message apps in the
for(PackageInfo pi : packageList) {
boolean b = isSystemPackage3(pi);
boolean c = isSystemPackage4(pi);
if (b || c){
packageList1.add(pi);
}
}
//sort by application name
final PackageItemInfo.DisplayNameComparator comparator = new PackageItemInfo.DisplayNameComparator(packageManager);
Collections.sort(packageList1, new Comparator<PackageInfo>() {
#Override
public int compare(PackageInfo lhs, PackageInfo rhs) {
return comparator.compare(lhs.applicationInfo, rhs.applicationInfo);
}
});
return null;
}
#Override
protected void onCancelled() {
super.onCancelled();
}
#Override
protected void onPreExecute() {
pDialog = new ProgressDialog(InstalledAppActivity.this);
pDialog.setMessage("Loading your apps...");
pDialog.show();
}
//Inefficient patch to prevent Window Manager error
#Override
protected void onPostExecute(Void result) {
apkList.setAdapter(new ApkAdapter(InstalledAppActivity.this, packageList1, packageManager));
try {
if ((this.pDialog != null) && this.pDialog.isShowing()) {
this.pDialog.dismiss();
}
} catch (final IllegalArgumentException e) {
// Handle or log or ignore
} catch (final Exception e) {
// Handle or log or ignore
} finally {
this.pDialog = null;
}
super.onPostExecute(result);
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
}
try this :
#Override
public Object onRetainNonConfigurationInstance() {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog = null;
}
if (asynTask!= null) {
asynTask.detach();
}
return ayncTask;
}
Declaring a non-static inner AsyncTask in your activity is not a good idea because it holds a reference to the activity and this could be a couse of the leak. However, various configuration changes could cause the OS to destroy and recreate the activity. There are a number of solutions and Rustam's anser is an example.
However, I prefer to user either AsyncTaskLoader or use some sort of asynchronous callback, like a broadcast. The asynchronous callback decouples your AsyncTask from the Activity.