-1

I am new to android development . I have an app which has background service, ArrayList of size 100. I am saving this ArrayList using SharedPreferences in onPause and onDestroy method.

When I am in the app it consumes a lot of ram (60MB) and when I press back button( i.e. both on pause and on destroy method is executed ) the ram consumption comes to 5MB ( which is fine as my background service is still running ).

But from the app if I press home button ( only on pause is executed ) it consumes 60MB of ram even when I am using other apps. If I clear my app in list of background apps, again my ram consumption comes to 5MB.

I believe it has something to do with onPause and onDestroy method.

What I want is when I press home button directly from app then it will consume only 5MB of ram ? Is it possible? What am I missing ?Is it because of ArrayList its consuming so much of ram ? How do i reduce my ram consumption ?

Here is the code: MainActivity.class

public class MainActivity_OffNet extends ListActivity implements Serializable{

private PackageManager packageManager = null;
private ArrayList<ApplicationInfo> applist = null;
private AppInfoAdapter listadaptor = null;
private  ArrayList<String> addblock_list;
private SharedPreferences settings;



@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_layout_off_net);

    boolean first_time_open = false;
    addblock_list = new ArrayList<String>(100);

    settings = getSharedPreferences("PREFS_NAME", 0);
    first_time_open = settings.getBoolean("FIRST_RUN", false);
    if (!first_time_open) {


            for(int i=0;i<100;i=i+1)
            {
                addblock_list.add("addblock");  
            }

     settings = getSharedPreferences("PREFS_NAME", 0);
     SharedPreferences.Editor editor = settings.edit();
     editor.putBoolean("FIRST_RUN", true);
     editor.commit();

        }
    else{



    String jsonString = settings.getString("addblock_list_string", null);
     Gson gson = new Gson();
     String[]  String_array_addblock_list=   gson.fromJson(jsonString,String[].class);
     List<String>favorites = Arrays.asList(String_array_addblock_list);
    favorites = new ArrayList(favorites);
    addblock_list.addAll(favorites);


  }
   AdView mAdView = (AdView) findViewById(R.id.adView);
   AdRequest adRequest = new AdRequest.Builder()
          .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
          .addTestDevice("abc") //Random Text
           .build();
    mAdView.loadAd(adRequest);
  }

@Override
protected void onResume() {
    // TODO Auto-generated method stub

    packageManager = getPackageManager();
    new GetApplicationInfo().execute();
    super.onResume();
}



@Override
protected void onPause() {

      Editor editor;
      editor = settings.edit();
      Gson gson = new Gson();
      String jsonString = gson.toJson(addblock_list);
      editor.putString("addblock_list_string", jsonString);
      editor.commit();


      startService(new Intent(this,BackgroundService.class));
      super.onPause();

}


@Override
protected void onDestroy() {

        Editor editor;
      editor = settings.edit();
      Gson gson = new Gson();
      String jsonString = gson.toJson(addblock_list);
      editor.putString("addblock_list_string", jsonString);
      editor.commit();

      startService(new Intent(this,BackgroundService.class));
      super.onDestroy();
}

public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu, menu);
    return true;
}

public boolean onOptionsItemSelected(MenuItem item) {
    boolean result = true;

    switch (item.getItemId()) {
    case R.id.menu_about: {
        displayAboutDialog();

        break;
    }
    default: {
        result = super.onOptionsItemSelected(item);

        break;
    }
    }

    return result;
}

private void displayAboutDialog() {
    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(getString(R.string.title));
    builder.setMessage(getString(R.string.description));


    builder.setPositiveButton("Rate Us Now", new DialogInterface.OnClickListener() {
           public void onClick(DialogInterface dialog, int id) {
               Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=com.san.offnet&hl=en"));
               startActivity(browserIntent);
               dialog.cancel();
           }
       });
    builder.setNegativeButton("No Thanks!", new DialogInterface.OnClickListener() {
           public void onClick(DialogInterface dialog, int id) {
                dialog.cancel();
           }
    });

    builder.show();
}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);

    ImageView addview = (ImageView) v.findViewById(R.id.add_icon);
    ApplicationInfo app = applist.get(position);
   if(app.packageName.equals("com.example.offnet")){

        Toast.makeText(MainActivity_OffNet.this, "You cannot select this app  ", Toast.LENGTH_SHORT).show();

    }

    else {

        if (addblock_list.get(position).equals(app.packageName)) {
            addview.setImageResource(R.drawable.ads);
            addblock_list.set(position, "addblock");
            Toast.makeText(MainActivity_OffNet.this, "Removed " + app.packageName, Toast.LENGTH_SHORT).show();


        } else {
            addview.setImageResource(R.drawable.adsblock);
            addblock_list.set(position, app.packageName);
            Toast.makeText(MainActivity_OffNet.this, "Added " + app.packageName, Toast.LENGTH_SHORT).show();



        }

    }


}

private ArrayList<ApplicationInfo> checkForLaunchIntent(ArrayList<ApplicationInfo> list) {
    ArrayList<ApplicationInfo> applist = new ArrayList<ApplicationInfo>();

    for (ApplicationInfo info : list) {
        try {
            if (null != packageManager.getLaunchIntentForPackage(info.packageName)) {
                applist.add(info);
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    return applist;
}

private class GetApplicationInfo extends AsyncTask<Void, Void, Void> {
    private ProgressDialog progress = null;

    @Override
    protected Void doInBackground(Void... params) {
        applist = checkForLaunchIntent( (ArrayList<ApplicationInfo>) packageManager.getInstalledApplications(PackageManager.GET_META_DATA));


        @SuppressWarnings("rawtypes")
        HashMap<Integer,ArrayList> yourHash = new HashMap<Integer,ArrayList>();
        yourHash.put(1,applist);
        yourHash.put(2,addblock_list);
        listadaptor = new AppInfoAdapter(MainActivity_OffNet.this,
            R.layout.row_list,yourHash);
        return null;
}

    @Override
    protected void onCancelled() {
        super.onCancelled();
    }

    @Override
    protected void onPostExecute(Void result) {
        setListAdapter(listadaptor);
        progress.dismiss();
        super.onPostExecute(result);
    }



    @Override
    protected void onPreExecute() {
        progress = ProgressDialog.show(MainActivity_OffNet.this, null,
                "Loading app info ...");
        super.onPreExecute();
    }




    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
    }
}
 }

AppInfoAdapter.class

public class AppInfoAdapter extends ArrayAdapter<HashMap<Integer,ArrayList>>{

private ArrayList<ApplicationInfo> appsList = null;
private Context context;
private PackageManager packageManager;
public ImageView addview;
private ArrayList<String> addblock_list;
private HashMap<Integer,ArrayList> yourHash;



@SuppressWarnings("unchecked")
public AppInfoAdapter(Context context, int textViewResourceId,
        HashMap<Integer,ArrayList> yourHash) {
    // TODO Auto-generated constructor stub
    super(context,textViewResourceId);

    this.context = context;
    this.yourHash = yourHash;
    packageManager = context.getPackageManager();
    appsList = (ArrayList<ApplicationInfo>) yourHash.get(1);
    addblock_list= (ArrayList<String>)yourHash.get(2);


}

@Override
public int getCount() {
    return ((null != appsList) ? appsList.size() : 0);
}


@Override
public HashMap<Integer, ArrayList> getItem(int position) {
    return yourHash;
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View view = convertView;
    if (null == view) {
        LayoutInflater layoutInflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = layoutInflater.inflate(R.layout.row_list, null);
    }

    ApplicationInfo data = appsList.get(position);
    if (null != data) {
        TextView appName = (TextView) view.findViewById(R.id.app_name);
        ImageView iconview = (ImageView) view.findViewById(R.id.app_icon);
        addview = (ImageView) view.findViewById(R.id.add_icon);
        appName.setText(data.loadLabel(packageManager));
        iconview.setImageDrawable(data.loadIcon(packageManager));

        if(addblock_list.get(position).equals(data.packageName)){

            addview.setImageResource(R.drawable.adsblock);

        }
        else{
            addview.setImageResource(R.drawable.ads);
        }



    }
    return view;
}
};

Ram consumption was high because of ArrayList of size 100 . Now i made the array dynamic . So my ram consumption reduced to 33mb. Now if i install this app i have no problems, but if i update the app , it will retrieve ArrayList of size 100 and create problems to me.

Is there a way ,when i update the app , the app should start from fresh( like a new install) ?

sandesh hegde
  • 34
  • 1
  • 12

2 Answers2

0

Try adding finish(); method in onStop(); method as onStop gets called when Home button is pressed adding finish will end your activity as well and will bring Ram consumption to normal i.e 5mb in your case.

mfaisalhyder
  • 2,250
  • 3
  • 28
  • 38
0

From you code, I found that onPause() and onDestroy() are total same methods. So, when you are pressing back or home button, the difference in RAM (5MB, 50MB) is not because of above methods.

While application is in paused state, android framework may re-gain memory in case of emergency. When you observe the difference (5MB and 50MB), android framework may have collected memory from your application.

The memory problems are coming because

  • Large size of String ArrayList or List

I suggest if you can either store this list in Sqlite database or fetch the list from web service call response This will eliminate your large arraylist for stroing addblock_list

Kushal
  • 8,100
  • 9
  • 63
  • 82
  • its true, it has nothing to do with on pause or on destroy , i reduced my arraylist by making it dynamic, so it ll hv abt 4 to 5 values., but still its eating lot of ram. How do i release the resource after i close the app? – sandesh hegde May 07 '15 at 15:26
  • perform resource realese in `onDestroy()` everytime. When you use any `inputstream` make sure that they are `closed` once use is done. Check where you can save memory by not creating more `String`, `array of any type` etc. For memory usage of your application, observe logs with tag `dalvikvm` while running your application.. and idntify in which scenario, memory use is increasing (live object size is increasing) – Kushal May 08 '15 at 04:15