【发布时间】:2015-04-29 19:22:23
【问题描述】:
我是安卓开发新手。我有一个具有后台服务的应用程序,大小为 100 的ArrayList。我正在使用SharedPreferences 在onPause 和onDestroy 方法中保存这个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