【问题标题】:Too much ram consumption when home button is pressed vs when back button is pressed按下主页按钮与按下返回按钮时的内存消耗过多
【发布时间】:2015-04-29 19:22:23
【问题描述】:

我是安卓开发新手。我有一个具有后台服务的应用程序,大小为 100 的ArrayList。我正在使用SharedPreferencesonPauseonDestroy 方法中保存这个ArrayList

当我在应用程序中时,它会消耗大量内存 (60MB),而当我按下返回按钮时(即在暂停和销毁方法都执行时),内存消耗会达到 5MB(这很好,因为我的后台服务仍在运行)。

但是,如果我按下主页按钮(仅在执行暂停时),即使在我使用其他应用程序时,它也会消耗 60MB 的内存。如果我在后台应用程序列表中清除我的应用程序,我的内存消耗量再次达到 5MB

我认为这与 onPause 和 onDestroy 方法有关。

我想要的是当我直接从应用程序按下主页按钮时,它只会消耗 5MB 的内存?是否可以?我错过了什么?是因为 ArrayList 消耗了这么多内存吗?如何减少内存消耗?

这里是代码: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;
}
};

由于 ArrayList 的大小为 100,RAM 消耗量很高。现在我使数组动态化。所以我的内存消耗减少到 33mb。现在如果我安装这个应用程序我没有问题,但如果我更新应用程序,它将检索大小为 100 的 ArrayList 并给我带来问题。

有没有办法,当我更新应用程序时,应用程序应该从新开始(如新安装)?

【问题讨论】:

  • “我错过了什么?” -- 你的代码。我们只能猜测你做错了什么。
  • 我把我的代码放在上面。你能提出一些解决方案吗?

标签: android ram onpause ondestroy


【解决方案1】:

尝试添加finish(); onStop() 中的方法;按下 Home 按钮时调用 onStop 方法添加完成也将结束您的活动,并使 Ram 消耗恢复正常,即在您的情况下为 5mb。

【讨论】:

  • 我添加了finish();在 onStop();方法,它不起作用,现在它在我按下返回按钮或按下主页按钮后消耗内存。
  • this.finish();或者写下你完整的activityName.finsish();可能这会有所帮助。
  • 它与暂停或销毁方法无关,我退出应用程序后如何释放资源?
【解决方案2】:

从您的代码中,我发现onPause()onDestroy() 是完全相同的方法。所以,当你按下backhome按钮时,RAM的差异(5MB50MB)并不是因为上述方法。

当应用程序处于paused 状态时,android 框架可能会在紧急情况下重新获得内存。当您观察到差异(5MB50MB)时,android 框架可能已经从您的应用程序中收集了内存。

内存问题来了,因为

  • 大字符串ArrayListList

我建议您是否可以将此列表存储在Sqlite 数据库中或从web service call response 获取列表这将消除您用于查找addblock_list 的大型数组列表

【讨论】:

  • 它是真的,它与暂停或销毁无关,我通过使其动态来减少我的数组列表,所以它会 hv abt 4 到 5 个值。但它仍然吃了很多 ram .关闭应用后如何释放资源?
  • 每次都在onDestroy() 中执行资源Realese。当您使用任何inputstream 时,请确保它们在使用完成后是closed。通过不创建更多Stringarray of any type 等来检查可以节省内存的位置。对于应用程序的内存使用情况,在运行应用程序时观察带有标签dalvikvm 的日志......并确定在哪种情况下内存使用量正在增加(活动对象大小正在增加)
猜你喜欢
  • 1970-01-01
  • 2019-10-26
  • 1970-01-01
  • 2022-10-08
  • 1970-01-01
  • 2018-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多