This Handler class should be static or leaks might occur (com.test.test3.ui.MainActivity.1)

android, android-handler, memory-leaks, static-class

Solution

Make your handler a static class.

The warning is a lint warning. You can disable the warning but its a useful info

Here's a list of Lint Check

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

Quoting from the source @

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

Avoid non-static inner classes in an activity if you don't control their life cycle, use a static inner class and make a weak reference to the activity inside.

The solution to this issue is to use a static inner class with a `WeakReference` to the outer class, as done in `ViewRoot` and its W inner class for instance.

Also check this discussion on android developers group. Check the solution by Romain Guy

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

Example from Romain Guy's solution from the above link

 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(); 
   }

Edit:

Example:

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);

            }

        };
}

Correct me if the above is wrong or has some issues.

You can also check this blog by Alex Lockwood

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

Problem

I am new to android and i try to develop a system but when i finish code the handler show this warning below show the code after I edit, the handler in event ontounch show the warning handler cannot be resolved. I try putting // to ignore the handler at i try run the application and its result in force close. ``` 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; } } ```

Original source

Related problems