2015-04-29 6 views
-1

Я новичок в разработке Android. У меня есть приложение, которое имеет фоновое обслуживание, ArrayList размера 100. Я сохраняю это ArrayList, используя SharedPreferences в и onDestroy метод.Слишком много потребляемой памяти при нажатии кнопки дома против нажатия кнопки возврата

Когда я нахожусь в приложении потребляет много оперативной памяти (60MB), и когда я нажимаю кнопку назад (т.е. как на паузу и уничтожить метод выполняется) расход барана приходит 5МБ (который отлично, поскольку мое фоновое обслуживание все еще работает).

Но из приложения, если я нажимаю кнопку «домой» (только при паузе), он потребляет 60 МБ оперативной памяти, даже если я использую другие приложения. Если я удалю свое приложение в списке фоновых приложений, снова мое потребление плунжера достигнет 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. Теперь я сделал массив динамическим. Таким образом, мое потребление бара сократилось до 33 Мб. Теперь, если я устанавливаю это приложение, у меня нет проблем, но если я обновляю приложение, он будет извлекать ArrayList размером 100 и создавать проблемы для меня.

Есть ли способ, когда я обновляю приложение, приложение должно начинаться со свежего (как новая установка)?

+0

«Что мне не хватает?» -- ваш код. Мы можем только догадываться, что вы делаете неправильно. – 323go

+0

Я поставил свой код выше. Можете ли вы предложить какое-то решение? –

ответ

0

Попробуйте добавить finish(); метод в onStop(); метод, так как onStop вызывается, когда нажата кнопка «Домой», добавление финиша также закончит вашу деятельность и приведёт потребление Ram к нормальному i.e 5mb в вашем случае.

+0

i added finish(); в onStop(); метод, его не работает, теперь его потребляющий барабан после того, как я нажму кнопку «Назад», или я нажму кнопку «домой». –

+0

this.finish(); или напишите свой полный активName.finsish(); может быть, это поможет. –

+0

не имеет ничего общего с методом паузы или по уничтожению, как я могу освободить ресурсы после выхода из приложения? –

0

От вас код, я обнаружил, что onPause() и onDestroy() являются общими же методами. Итак, когда вы нажимаете кнопку back или home, разница в ОЗУ (5MB, 50MB) не из-за вышеописанных методов.

Пока приложение находится в состоянии paused, каркас Android может повторно получить память в случае чрезвычайной ситуации. Когда вы наблюдаете разницу (5MB и 50MB), инфраструктура Android может собирать память из вашего приложения.

Проблемы памяти приходит, потому что

  • Большого размер строка ArrayList или List

Я предлагаю, если вы можете сохранить этот список в Sqlite базы данных или принести список из web service call response Это позволит устранить ваш большой арраист для строгания addblock_list

+0

его истинный, он не имеет ничего общего с паузой или уничтожением, я уменьшил свой arraylist, сделав его динамичным, так что он будет содержать от 4 до 5 значений., Но все же его едят много барана. Как я могу освободить ресурс после закрытия приложения? –

+0

выполнить ресурс realese in 'onDestroy()' каждый раз. Когда вы используете какой-либо «входной поток», убедитесь, что они «закрыты», когда используется. Проверьте, где вы можете сохранить память, не создавая больше 'String',' массив любого типа' и т. Д. Для использования памяти вашего приложения наблюдайте журналы с тегом 'dalvikvm' при запуске вашего приложения .. и idntify, в каком сценарии используется память (размер живого объекта увеличивается) – Kushal