1

At particular point of time in my app, I want to restart the app completely i.e. killing the process associated with the app and then restarting it again. I want to do this to free up heap space as my app contains lot of bitmaps.

I used this SO link with the highest voted answer and created following extra activity as following:

/** This activity shows nothing; instead, it restarts the android process */
public class MagicAppRestart extends Activity {
    // Do not forget to add it to AndroidManifest.xml
    // <activity android:name="your.package.name.MagicAppRestart"/>
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        System.exit(0);
    }
    public static void doRestart(Activity anyActivity) {
        anyActivity.startActivity(new Intent(anyActivity.getApplicationContext(), MagicAppRestart.class));
    }
}

and calling this activity as MagicAppRestart.doRestart(this); from the required place in another activity.

Now, the issue is this works fine on android 2.3 but on 4.0, this code only exits the app but do not restart it.

Am I doing anything wrong? Is there exist a solution for this issue which will work on all OS?

Also, I have already tried following code, it restarts the but not process and hence does not free up the heap, so it is of no use to me:

Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);

Any help appreciated !

Edit

I have 7 activities in my app including home activity. Barring home activity, other 6 activities use ViewFlipper with 5-8 screens.

I'm using unbindDrawables() in onStop() and onDestroy() of every activity but it releases only little portion of the memory.

Hence I'm looking to completely restart the app process.

Edit 2

I just came across this:

In addition, Android changed the way bitmap memory is allocated. Prior to Android 3.0, bitmaps were allocated in native memory, with only a small descriptor kept on the Java heap; now the entire bitmap is allocated from the Java heap. This can lead to the Java heap being used up very quickly if multiple bitmaps are kept in memory.

I guess this is the reason why my approach is working in device with 2.3OS and not on device with 4.0 OS.

Community
  • 1
  • 1
GAMA
  • 5,958
  • 14
  • 79
  • 126
  • Why you want to restart your app`, maybe we can help you to do a other approach – A.S. Oct 11 '13 at 08:07
  • as mentioned in question: *to free up heap space as my app contains lot of bitmaps*... – GAMA Oct 11 '13 at 08:08
  • @GAMA Call `bitmap.recycle()` before destroying activity. It would help – Glenn Oct 11 '13 at 08:09
  • If you are working with images, also have a look at this: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html – A.S. Oct 11 '13 at 08:10
  • I'm setting bitmaps from xml and not from java class – GAMA Oct 11 '13 at 08:10
  • Please check edit in the question. – GAMA Oct 11 '13 at 08:16
  • @GAMA do you run into memory leaks is your application running slow? – Raghunandan Oct 11 '13 at 08:27
  • It's not running slow, but used heap keeps increasing gradually as seen from eclipse. At one point I did faced **bitmap.outofmemory** exception. I added `android:largeheap=true`. Now app don't crash but still heap consumption is the same. – GAMA Oct 11 '13 at 08:29
  • @GAMA GC kicks in when needs to free memory. Did you try scaling your image down. Also i see no reason fro you quit and restart – Raghunandan Oct 11 '13 at 08:31
  • @GAMA for android 3.0 and below use `bitmap.reccyle()` check this http://developer.android.com/training/displaying-bitmaps/manage-memory.html. Do not use `System.gc(); Runtime.getRuntime().gc()`. – Raghunandan Oct 11 '13 at 08:35
  • I'm using `System.gc(); Runtime.getRuntime().gc();` in onStop() and onDestroy(). – GAMA Oct 11 '13 at 08:35
  • How do I use `bitmap.reccyle()` since I'm setting bitmaps from xml and not from java class – GAMA Oct 11 '13 at 08:37

5 Answers5

1

You should not call System.exit(0). It is a bad idea to quit and restart your app.

Quoting Romain Guy from https://groups.google.com/forum/#!topic/android-developers/G_D3pKnGLt0

(Romain Guy): The user doesn't, the system handles this automatically. That's what the activity lifecycle (especially onPause/onStop/onDestroy) is for. No matter what you do, do not put a "quit" or "exit" application button. It is useless with Android's application model. This is also contrary to how core applications work.

To know more check the below link

Is quitting an application frowned upon?

You should code in such a way that you don't run into memory leaks.

Managing Bitmap Memory

http://developer.android.com/training/displaying-bitmaps/manage-memory.html

Also check this link on Memory management

https://www.youtube.com/watch?v=_CruQY55HOk

Edit:

You can bind the drawable in onResume an unbind in onPause.

Community
  • 1
  • 1
Raghunandan
  • 132,755
  • 26
  • 225
  • 256
  • 1
    I know, `System.exit(0)` is not the best practices in android. but if the requirements demands something like this, I have to use it, I guess. Also, I have already checked for memory leaks. It's just that there are lots of bitmaps. – GAMA Oct 11 '13 at 08:09
  • @GAMA you should rethink your design rather than using `System.exit(0)`. It is not recommended. recycle bitmaps and do check the second link for the same – Raghunandan Oct 11 '13 at 08:10
  • @GAMA `recycle` them. Restarting your app is not a good solution. – Simon Oct 11 '13 at 08:10
  • I'm setting bitmaps from xml and not from java class – GAMA Oct 11 '13 at 08:10
  • @GAMA you can remove them in `onPause` and recycle them when not in use – Raghunandan Oct 11 '13 at 08:12
  • Then `finish()` your activity and see this. http://stackoverflow.com/questions/12395068/unbinding-drawables-onpause-causing-unresponsive-back-navigation-and-skipping. It will allow GC to clear the heap. – Simon Oct 11 '13 at 08:12
  • @GAMA pls check link 2 and 3 go through it and re think your design. binding and unbinding the drawable is fine. unbind in `onPause` and bind again in `onResume`. – Raghunandan Oct 11 '13 at 08:18
  • regarding **unbind in onPause and bind again in onResume**, I don't have any issue till I'm in the activity. so any solution should be used in onStop() and onDestroy()... – GAMA Oct 11 '13 at 08:36
  • @GAMA you are free to do whatever you want. Sorry off the op of my head. You should unbind in `onPause`. – Raghunandan Oct 11 '13 at 09:11
  • I didn't mean that way dude. I was just trying to go with the requirements. – GAMA Oct 11 '13 at 10:28
1

You can't clear the heap. Read this for better understanding.

Hope it helps.

Community
  • 1
  • 1
RussVirtuoso
  • 900
  • 1
  • 9
  • 20
  • I have tested that restarting the application process clears the app as you are completely killing the running instance of the app. – GAMA Oct 11 '13 at 08:28
0

Try this. It works for me:

Intent it = new Intent();

it.setComponent(new ComponentName(YourActivity.this.getPackageName(),YourActivity.class.getName()));
it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_SINGLE_TOP);
YourActivity.this.getApplicationContext().startActivity(it);
silvia_aut
  • 1,481
  • 6
  • 19
  • 33
0

After suggestions from some people, I concluded it's not ideal/recommended to exit/restart the app through code when the app is running.

So, what I have done is - set a flag to identify home button click i.e.exit of app

At that time, I call android.os.Process.killProcess(android.os.Process.myPid()); to completely kill the process of current app and to avoid running of app in background.

Thanks all !

GAMA
  • 5,958
  • 14
  • 79
  • 126
0

Try the top voted answer of Oleg Koshkin in this how to programmatically "restart" android app? . Hope this will help you.

Intent mStartActivity = new Intent(context, StartActivity.class);
int mPendingIntentId = 123456;
PendingIntent mPendingIntent = PendingIntent.getActivity(context,  mPendingIntentId,    mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
System.exit(0);
Community
  • 1
  • 1
Kanchan Chowdhury
  • 433
  • 1
  • 5
  • 15