Free up memory on Android when push Back Button - android

I have 2 activities, Activity1 and Activity2. In Activity1 I have a button to go to Activity2.
Activity2 has a lot of Edittext and other Views.
When I start the app, the memory of the process is 10mb. If I click on the button and Activity2 is loaded, my memory's process is about 59mb.
The issue is, in Activity2, if I push Back Button, I return to Activity1 and my memory's process is about 59mb, and I don't need this information about Activity2.
Now, If I click again the button, I have an OutOfMemory.
How can I force to free up the memory when I push Back Button?
I try to call finish() and System.gc() but It doesn't work.
Thank you

try this one....
first close your activity...
use following code...
public class ur_clss extends Activity {
private ur_class c1;
//ur content here
#Override
public void onBackPressed () {
c1.finishActivity(0);
}
}

You need to override the BackButton and free up the memory when it is pressed.
#Override
public void onBackPressed()
{
Activity.finish() // the activity that you want to terminate
}
Or, there is another way to do it. When you start the new activity, the old activity goes onPause(). You could try calling finish() in the onPause() of the old activity.

This is the structure of the code:
public class Activity2 extends Activity {
// Global variables
private CarregaOperacions carrega_operacions;
private TableLayout taula;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Some code of UI
// Show a ProgressBar
loadProgress();
carrega_operacions = new CarregaOperacions(Activity2.this);
carrega_operacions.execute(null);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK))
{
finish();
}
return super.onKeyDown(keyCode, event);
}
static class CarregaOperacions extends AsyncTask<Void, Void, Void> {
WeakReference<Activity2> context;
Activity2 act;
public CarregaOperacions(Activity2 activity) {
context = new WeakReference<Activity2>(activity);
act = context.get();
}
#Override
protected Void doInBackground(Void... arg0) {
act.carregaOperacions();
return null;
}
protected void onPostExecute(Void result) {
ArrayList<LinearLayout> llista = act.getLlistaFiles();
for (int i = 0; i < llista.size(); i++ ) {
act.getTable().addView(llista.get(i));
}
act.getScroll().setVisibility(View.VISIBLE);
act.treuProgres();
}
}
With this code, I explain a bit:
The real case is, Activity1 calls a TabActivity, that has the Activity2. Activity2 loads a lot of registers, and I do this asynchronously. I Override onKeyDown in Activity2 and on the TabActivity, but it seems that only is onKeyDown's Activity2 executed.

Related

exit() and killProcess() doesn't work

I'm trying to close my app when back button is pressed. So I overridden onBackPressed() in my activity:
public void onBackPressed()
{
Process.killProcess(Process.myPid());
}
I also tried:
public void onBackPressed()
{
exit(0);
}
my app got 3 tasks and 5 activities: A, B, C, D and E. Where I placed A, B and C in one task While D and E got their own tasks. I want to exit the app when the back button is pressed in activities A, D and E.
I try toasting from onBackPressed() and function callback works fine.
When I click the back button on my device in activities A or D or E it just goes to the previous activity from another task !!
public class CloseApplication
{
private static boolean isToCloseApp = false;
public static boolean isToCloseApp()
{
return isToCloseApp;
}
public static void updateFlagToCloseTheApp(boolean flag)
{
isToCloseApp = flag;
}
}
onBackKey Press UseCode
public void onBackPressed()
{
CloseApplication.updateFlagToCloseTheApp(true);
finish();
}
One more Thing in each activity of your application Override the onResume method.
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if(CloseApplication.isToCloseApp())
{
finish();
}
}
mark the answer solve if it solve your problem and so that it helps the other to find the answer.

How to delivery results from long-running async runnable to activity?

An activity launches a long-running async task that runs in a background thread. This background task should return a result to the activity when completed (for instance, to notify a user about an operation success or failure)
Result could arrive at any time. Problems are that:
- the original instance object of the activity could be destroyed (e.g. a screen was rotated)
- there is no ready activity (the old activity destroyed, the new one is not started yet)
- a user changed the visible activity (pressed a back button, or pressed a home button, etc)
Please advice a design pattern for such technical task.
Result could arrive at any time. Problems are that: - the original instance object of the activity could be destroyed (e.g. a screen was rotated)
You could implement a rotation-aware AsyncTask, as described by Mark Murphy ("CommonsWare") here.
there is no ready activity (the old activity destroyed, the new one is not started yet)
If you mean because of the transition between onRetainNonConfigurationInstance() and onCreate(), read the post above, he explains why this shouldn't be a problem.
a user changed the visible activity (pressed a back button, or pressed a home button, etc)
Otherwise, if you mean different Activities, long term data loading, I believe you could implement your own Loader (e.g., an AsyncTaskLoader) with satisfactory results, since they abstract all the usual life cycle overhead you would otherwise need to take care of.
There are a few ways to tackle this problem.
AsyncTask:
public class AsyncTask<Void, Void, T extends Parcelable> {
private final Context mApplicationContext;
public MyAsyncTask(Context context) {
mApplicationContext = context.getApplicationContext();
}
public void onPostExecute(T result) {
Intent intent = new Intent(String.format("%s.DONE", mApplicationContext.getPackageName()));
intent.putExtra("Data", result);
mApplicationContext.sendBroadcast(intent);
}
}
And then in your activity:
public class FooActivity extends Activity {
BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent data) {
if (TextUtils.equals(data.getAction(), String.format("%s.DONE", context.getPackageName()) {
Object o = data.getParacelableExtra("DONE");
// DO SOMETHING WITH IT
}
}
};
public void onCreate(Bundle b) {
...
registerReceiver(mReceiver, new IntentFilter(String.format("%s.DONE", getPackageName())));
}
public void onDestroy() {
...
unregisterReceiver(mReceiver);
}
}
OR
try this:
public class MYActivity extends Activity implements MyCustomAsyncTask.Listener {
private MyCustomAsyncTask<?, ?, ?> mTask;
public Object onRetainNonConfigurationInstance() {
if (mTask != null) {
mTask.setListener(null);
}
return mTask;
}
public void onCreate(Bundle b) {
mTask = getLastNonConfigurationInstance();
if (mTask == null) {
mTask = new MyCustomAsyncTask(....);
}
mTask.setListener(this);
}
MyCustomAsyncTask
public class MyCustomAsyncTask<Void, Void, Object> extends AsyncTask {
public interface Listener {
public void doSomethingWithThis(Object o);
}
private mListener;
public void setListener(Listener listener) {
mListener = listener;
}
public void onPostExecute(Object result) {
if (mListener != null) {
mListener.doSomethingWithThis(result);
}
}
...
}

How can I activity close in Android?

I have three classActivity created. One is super class and other sub class and third is HomeActivity.
Code for super class is :
public class MyActivity extends Activity {
Button btnHome = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void onHomeClick(View view) {
String LOG_TAG = "Akshar";
System.out.println("Hello11111");
btnHome = (Button) view;
Log.v(LOG_TAG, "index=" + btnHome);
}
}
and my subclass code is :
public class ChooseIsland extends MyActivity {
Button btn_home = null;
MyActivity ob1 = new MyActivity();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chooseiland);
addListenerOnButton();
}
private void addListenerOnButton() {
// TODO Auto-generated method stub
ob1.onHomeClick(btn_home);
}
}
Now I want to go on Home page when click so when I write ?
Intent intent = new Intent(this, HomeActivity.class);
There is no close operation as such in android. You should make sure you do not save anything in stack so whenever you are traversing from one activity to other, make sure you use intent flags to clear history or top of stack and then call finish.
finish() will close the current activity and the previous activity will come to foreground.
Generally to we write finish() method to close activity.

Run code when Android app is closed/sent to background

I have an Android application which sends some data to a webservice. I need to send this data as soon as the application is closed or sent to background.. But how do I accomplish this?
My current solution is to run it on the OnPause() on my home activity, but I need this to run no matter which activity the user is on when closing the app.. Is this possible or do I have to add the OnPause method to all activities?
Check this solution first https://stackoverflow.com/a/5862048/1037294 before you decide to use the code below!
To check if your application is sent to background, you can call this code on onPause() or onStop() on every activity in your application:
/**
* Checks if the application is being sent in the background (i.e behind
* another application's Activity).
*
* #param context the context
* #return <code>true</code> if another application will be above this one.
*/
public static boolean isApplicationSentToBackground(final Context context) {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks = am.getRunningTasks(1);
if (!tasks.isEmpty()) {
ComponentName topActivity = tasks.get(0).topActivity;
if (!topActivity.getPackageName().equals(context.getPackageName())) {
return true;
}
}
return false;
}
For this to work you should include this in your AndroidManifest.xml
<uses-permission android:name="android.permission.GET_TASKS" />
This is the method that I used and it seems to work pretty well:
I have a top level Application class of my own that extends Application as such
public class MyApplication extends Application implements Application.ActivityLifecycleCallbacks {
You also need to register this Application object in your manifest file:
<application android:label="#string/app_name" android:icon="#drawable/ic_launcher" android:name=".MyApplication">
Notice how I also implement the ActivityLifeCycleCallbacks interface. This interface has the following methods:
public static interface ActivityLifecycleCallbacks {
void onActivityCreated(android.app.Activity activity, android.os.Bundle bundle);
void onActivityStarted(android.app.Activity activity);
void onActivityResumed(android.app.Activity activity);
void onActivityPaused(android.app.Activity activity);
void onActivityStopped(android.app.Activity activity);
void onActivitySaveInstanceState(android.app.Activity activity, android.os.Bundle bundle);
void onActivityDestroyed(android.app.Activity activity);
}
You need to implement those methods and then register for these events in your applications onCreate() as follows
#Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(this);
}
This will then call the callback (the MyApplication object) whenever an activity lifecycle method happens such as onCreate(), onPause etc.
In your onActivityPaused() you can then check if the app was backgrounded or not by calling #peceps method : isApplicationSentToBackground(...)
This is what my code looks like then...
/**
* Application.ActivityLifecycleCallbacks methods
*/
#Override
public void onActivityCreated(Activity activity, Bundle bundle) {
}
#Override
public void onActivityStarted(Activity activity) {
}
#Override
public void onActivityResumed(Activity activity) {
}
#Override
public void onActivityStopped(Activity activity) {
try {
boolean foreground = new ForegroundCheckTask().execute(getApplicationContext()).get();
if(!foreground) {
//App is in Background - do what you want
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
#Override
public void onActivityPaused(Activity activity) {
}
#Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
#Override
public void onActivityDestroyed(Activity activity) {
}
Create a new class to go the Foreground checking (which is an async. task). See check android application is in foreground or not? for more.
class ForegroundCheckTask extends AsyncTask<Context, Void, Boolean> {
#Override
protected Boolean doInBackground(Context... params) {
final Context context = params[0];
return isAppOnForeground(context);
}
private boolean isAppOnForeground(Context context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
if (appProcesses == null) {
return false;
}
final String packageName = context.getPackageName();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
return true;
}
}
return false;
}
}
Edit
This answer only serves for one purpose, that is, running a code in onPause() for all activities. It doesn't let you run a code when your app is sent to background.
Original Answer
Make an Activity named YourBasicActivity and override its onPause() method and extend every Activity from YourBasicActivity
Maybe this can be helpfull, tell me if it worked for you.
only when you return from background the value of activities would be 0 (zero)
the rest of the times would be a number higher than 0(zero) when the onRestart()
is executed.
public class FatherClass extends Activity {
private static int activities = 0;
public void onCreate(Bundle savedInstanceState, String clase) {
super.onCreate(savedInstanceState);
}
protected void onRestart()
{
super.onRestart();
if(activities == 0){
Log.i("APP","BACK FROM BACKGROUND");
}
}
protected void onStop(){
super.onStop();
activities = activities - 1;
}
protected void onStart(){
super.onStart();
activities = activities + 1;
}
}
All of your classes must extend from this class for this to work.
Explanation: The onStart is executed one the activity is "visible" and the onStop when the activity is "not visible". So when your APP (it says APP not activity) goes to background all the activities are "not visible" so they execute the onStop method, so the idea behind this is to ADD ONE each time an activity es started, and SUBTRACT ONE each time an activity es hided, so if the value of the variable "activities" is zero that means that all the activities that where started in some point are now not visible, so when you APP returns from background and executes the onRestart method on the activity in "front" you can check whether comes from background or is just restarting an activity.
you can use onAppForegroundStateChange() method which call when app is open and closed.this method is only called when your app comes in foreground/background.
onAppForegroundStateChange() method is better then you used onPause() method because onPause method is also called every time when you go to other activity.
you can use this method like that
public class MyApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
AppForegroundStateManager.getInstance().addListener(this);
}
#Override
public void onAppForegroundStateChange(AppForegroundStateManager.AppForegroundState newState) {
if (AppForegroundStateManager.AppForegroundState.IN_FOREGROUND == newState) {
// App just entered the foreground. Do something here!
} else {
// App just entered the background. Do something here!
}
}
}
override the onStop() method of your Home activity and run the code there.
I think you need to run your own thread which will check whether all running activities in background or destroyed.
MyBasicActivity extends Activity
{
private static ArrayList<MyBasicActivity> activities=new ArrayList<MyBasicActivities);
private boolean started;
public void onCreate()
{
activities.add(this);
}
public void onDestroy()
{
activities.remove(this);
}
public void onStart()
{
this.started=true;
}
public void onPause()
{
this.started=false;
}
public boolean isStarted()
{
return started;
}
}
MyThread implements Runnable
{
private ArrayList<MyBasicActivity> activities;
public MyThread(ArrayList<MyBasicActivity> activities)
{
this.activities=activities;
}
void run()
{
while(!stopped)
{
boolean inBackground=true;
for(MyBasicActivity activity:activities)
{
if(activity.isStarted())
{
inBackground=false;
break;
}
}
if(inBackground)
//run your code here;
sleep(10000); //10 secs
}
}
}
If you are trying to submit/save data the user input, there are better ways to go about it than doing it when he tries to close the app. There are many ways to close an app. The user could even turn down the phone. So it's hard to take precautions against all of them.
I'd suggest you submit the data everytime the user stops writing, every any number of seconds or when he presses a button for example if your call to the webservice is too slow.
This way it's more safeproof and it's easier to implement.

How to destroy an activity in Android?

While the application is running, I press the HOME button to close the application. When I start the application again, it resumes on the page displayed prior to clicking on HOME. I want the application to start with the initial display instead. I have used finish() to finish the activity but it is not working. Any suggestions?
Most likely you have several instances of the same activity. To resolve this kind of issues create your own parent Activity class e.g. MyRootActivity which will hold static list of all of available/alive activities:
public class MyRootActivity extends Activity
{
private static final String TAG=MyRootActivity.class.getName();
private static ArrayList<Activity> activities=new ArrayList<Activity>();
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
activities.add(this);
}
#Override
public void onDestroy()
{
super.onDestroy();
activities.remove(this);
}
public static void finishAll()
{
for(Activity activity:activities)
activity.finish();
}
}
For that all of your activities need to be children of MyRootActivity.
Then when you are about to sure that you're closing your application - just call MyRootActivity.finishAll();
Create a static Activity object which activity finish on other activity and assign activity in this i.e you can can add more activities
public class demoActivity extends AppCompatActivity {
public static Activity self_intent;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.demo_activity);
selfintent=this;
}
//Other functions--------------
}
do same for other activities
on other
public class finishingActivity extends AppCompatActivity {
public Button activityCloseBtn;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.finishing_activity);
activityCloseBtn= (Button) view.findViewById(R.id.activity_close_btn);
activityCloseBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
demoActivity.selfintent.finish(); //for finish demoActivityactivity
//for other activities Activity.selfintent.finish();
finish(); //for finish current activity
}
});
try calling super.onPause() first and later call finish() inside your onPause() stub

Categories

Resources