Этот класс обработчика должен быть статическим или может возникнуть утечка (com.test.test3.ui.MainActivity.1)

Я новичок в android, и я пытаюсь разработать систему, но когда я закончу код, обработчик покажет это предупреждение

Ниже, показывается код после редактирования, обработчик в событии ontounch показывает, что обработчик предупреждения не может быть разрешен. Я пытаюсь положить // игнорировать обработчик при попытке запустить приложение и его результат в силе закрыть.

public class MainActivity extends Activity { protected static final int STOP = 100; ImageView iv; private ProgressBar pb; LinearLayout ll; private AnimationDrawable anim; ScrollView sv; private SQLiteDatabase db; private boolean flagscanning = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ll = new LinearLayout(this); new HandlerClass(this); db = SQLiteDatabase.openDatabase(Environment.getExternalStorageDirectory()+"/antivirus.sqlite", null, SQLiteDatabase.OPEN_READONLY); iv = (ImageView) this.findViewById(R.id.imageView1); //扫描病毒进度条 pb = (ProgressBar) this.findViewById(R.id.progressBar1); ll = (LinearLayout) this.findViewById(R.id.ll); //设置ImageView背景资源为动画文件 iv.setBackgroundResource(R.drawable.bg); //sv用来显示病毒的扫描结果 sv = (ScrollView) this.findViewById(R.id.scrollView1); anim = (AnimationDrawable) iv.getBackground(); } private static class HandlerClass extends Handler{ private final WeakReference<MainActivity> mTarget; public HandlerClass(MainActivity context){ mTarget = new WeakReference<MainActivity>((MainActivity) context); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); MainActivity target = mTarget.get(); if(msg.what==STOP){ target.ll.removeAllViews(); //anim.stop(); } String str = (String) msg.obj; TextView tv = new TextView(target); tv.setText(str); target.ll.setOrientation(LinearLayout.VERTICAL); target.ll.addView(tv); //sv.scrollBy(0, 20); System.out.println(str); } }; @Override public boolean onTouchEvent(MotionEvent event) { //如果程序正在杀毒过程中,拒绝再次启动杀毒线程 if(flagscanning){ return false; } //如果用户触摸屏幕,则开启杀毒线程 if (event.getAction() == MotionEvent.ACTION_UP) { flagscanning= true; anim.start(); new Thread() { public void run() { // 获取每一个应用程序的签名,签名须与数据库的签名想比较 List<PackageInfo> infos = getPackageManager() .getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_SIGNATURES); //设置进度条的扫描范围 pb.setMax(infos.size()); int total = 0; int virustotal = 0;//设置初始病毒数为0 for (PackageInfo info : infos) { total++; try { sleep(20);//只为便于观察扫描效果和进度,无实质作用 } catch (InterruptedException e) { e.printStackTrace(); } Message msg = Message.obtain(); msg.obj = "正在扫描" + info.packageName; _handler.sendMessage(msg);_ Signature[] signs = info.signatures; String str = signs[0].toCharsString(); String md5 = MD5Encoder.encode(str); //将应用程序签名与数据库中保存的签名进行比较,如果相一致,则使病毒数加1,并通过handler在界面显示病毒包名 Cursor cursor = db.rawQuery("select desc from datable where md5=?",new String[] { md5 }); if (cursor.moveToFirst()) { String desc = cursor.getString(0); msg = Message.obtain(); msg.obj = info.packageName + ": " + desc; _handler.sendMessage(msg);_ virustotal++; } cursor.close(); pb.setProgress(total); } Message msg = Message.obtain(); msg.what = STOP; msg.obj = "扫描完毕 ,共发现" + virustotal + "个病毒"; _handler.sendMessage(msg);_ flagscanning = false; pb.setProgress(0); }; }.start(); } return super.onTouchEvent(event); } @Override protected void onDestroy() { if (db.isOpen()) db.close(); super.onDestroy(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } } 

Сделайте свой обработчик статическим классом.

Предупреждение является предупреждением. Вы можете отключить предупреждение, но его полезная информация

Вот список Lint Check

http://tools.android.com/tips/lint-checks

Цитата из источника @

http://android-developers.blogspot.in/2009/01/avoiding-memory-leaks.html

Избегайте нестатических внутренних классов в деятельности, если вы не контролируете их жизненный цикл, используйте статический внутренний класс и слабо ссылаетесь на активность внутри.

Решение этой проблемы заключается в использовании статического внутреннего класса с WeakReference для внешнего класса, например, в ViewRoot и его внутреннем классе W.

Также проверьте это обсуждение группы разработчиков Android. Проверьте решение Ромен Гай

https://groups.google.com/forum/#!topic/android-developers/1aPZXZG6kWk

Пример из решения Ромен Гая из приведенной выше ссылки

  class OuterClass { class InnerClass { private final WeakReference<OuterClass> mTarget; InnerClass(OuterClass target) { mTarget = new WeakReference<OuterClass>(target); } void doSomething() { OuterClass target = mTarget.get(); if (target != null) target.do(); } 

Редактировать:

Пример:

 public class MainActivity extends Activity { LinearLayout ll; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ll = new LinearLayout(this); new HandlerClass(this); } private static class HandlerClass extends Handler{ private final WeakReference<MainActivity> mTarget; public HandlerClass(MainActivity context) { mTarget = new WeakReference<MainActivity>((MainActivity) context); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); MainActivity target = mTarget.get(); if (target != null) if(msg.what==1){ target.ll.removeAllViews(); // anim.stop(); } String str = (String) msg.obj; TextView tv = new TextView(target); tv.setText(str); target.ll.setOrientation(LinearLayout.VERTICAL); target.ll.addView(tv); //sv.scrollBy(0, 20); System.out.println(str); } }; } 

Исправьте меня, если вышеуказанное неверно или имеет некоторые проблемы.

Вы также можете проверить этот блог Алексом Локвудом

http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html

Когда вы определяете такой анонимный внутренний класс , этот класс переопределяется для каждого экземпляра MainActivity . По-видимому, Android SDK флаги, которые могут утечка этих определений классов. Самое простое решение – сделать его статическим внутренним классом, который ссылается на MainActivity в конструкторе:

 public class MainActivity extends Activity { //Fields and methods of MainActivity... private static final class MainHandler extends Handler { private final MainActivity caller; private MainHandler(final MainActivity caller) { this.caller = caller; } @Override public void handleMessage(Message msg) { //Your existing logic } } } 
Intereting Posts
Android Studio adb – устройство USB не найдено – разрешение Verizon Android Studio не запускается: Fatal error initializing 'com.intellij.util.indexing.FileBasedIndex Admob говорит: «Сервер ответил, что нет рекламы» Построить проект Android с Jenkins: не удалось инициализировать аналитику «Не удалось установить на USB-накопитель или SD-карту» приложение для установки ошибок на устройствах Samsung Как сделать изображение заполнить RelativeLayout фон без растяжки Строка Json для объектов области, самый быстрый способ Почему нет API Android для получения текущей активности? Преобразование String в Integer / Float / Double Поиск декартовых координат другого смартфона? Служба Android для проверки подключения к Интернету? Как фильтровать MotionEvent.getAction () на уровне API 3 (нет ACTION_MASK) Есть ли что-нибудь, что может сделать масляный нож, что привязка данных не может? Как преобразовать карту в байты и сохранить на внутреннем хранилище Идентификатор заказа Google Play обновлен до нового формата