这个处理程序类应该是静态的或可能发生泄漏(com.test.test3.ui.MainActivity.1) [英] This Handler class should be static or leaks might occur (com.test.test3.ui.MainActivity.1)

查看:263
本文介绍了这个处理程序类应该是静态的或可能发生泄漏(com.test.test3.ui.MainActivity.1)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来的Andr​​oid和我尝试​​开发一个系统,但是当我完成c中的处理程序$ C $显示此警告

下图显示了code我编辑后,在事件ontounch显示警告处理程序的处理程序无法得到解决。我尝试把//忽略处理程序,在我尝试运行该应用程序及其结果的强制关闭。

 公共类MainActivity延伸活动{



受保护的静态最终诠释STOP = 100;
ImageView的IV;
私人进度PB;
的LinearLayout LL;
私人AnimationDrawable动画;
滚动型SV;
私人SQLiteDatabase分贝;
私人布尔flagscanning = FALSE;


@覆盖
保护无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_main);
    LL =新的LinearLayout(本);
    新HandlerClass(本);

            DB = SQLiteDatabase.openDatabase(Environment.getExternalStorageDirectory()+/ antivirus.sqlite,空,SQLiteDatabase.OPEN_READONLY);
            IV =(ImageView的)this.findViewById(R.id.imageView1);
                    //扫描病毒进度条
            PB =(进度)this.findViewById(R.id.progressBar1);
            LL =(的LinearLayout)this.findViewById(R.id.ll);
                    //设置ImageView的背景资源为动画文件
            iv.setBackgroundResource(R.drawable.bg);
                    // SV用来显示病毒的扫描结果
            SV =(滚动型)this.findViewById(R.id.scrollView1);
            动画=(AnimationDrawable)iv.getBackground();
}

私有静态类HandlerClass扩展处理程序{
    私人最终的WeakReference< MainActivity> mTarget;
    公共HandlerClass(MainActivity上下文){
        mTarget =新的WeakReference< MainActivity>((MainActivity)上下文);
    }

    @覆盖
    公共无效的handleMessage(信息MSG){
        super.handleMessage(MSG);
        MainActivity目标= mTarget.get();
         如果(msg.what == STOP){
             target.ll.removeAllViews();
             //anim.stop();

             }
         字符串str =(字符串)msg.obj;
         TextView的电视=新的TextView(目标);
         tv.setText(STR);
         target.ll.setOrientation(LinearLayout.VERTICAL);
         target.ll.addView(电视);
         //sv.scrollBy(0,20);

        的System.out.println(STR);

    }
};


@覆盖
公共布尔的onTouchEvent(MotionEvent事件){
    //如果程序正在杀毒过程中,拒绝再次启动杀毒线程
    如果(flagscanning){
        返回false;
    }

    //如果用户触摸屏幕,则开启杀毒线程
    如果(event.getAction()== MotionEvent.ACTION_UP){
        flagscanning = TRUE;
        anim.start();
        新的Thread(){
            公共无效的run(){
                //获取每一个应用程序的签名,签名须与数据库的签名想比较
                名单< PackageInfo>相关信息= getPackageManager()
                        .getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_SIGNATURES);
                //设置进度条的扫描范围
                pb.setMax(infos.size());
                INT总= 0;
                INT virustotal = 0; //设置初始病毒数为0
                对于(PackageInfo信息:相关信息){
                    总++;
                    尝试 {
                        睡眠(20); //只为便于观察扫描效果和进度,无实质作用
                    }赶上(InterruptedException异常E){
                        e.printStackTrace();
                    }
                    消息味精= Message.obtain();
                    msg.obj =正在扫描+ info.packageName;
                    _handler.sendMessage(MSG); _
                    签名[]标志= info.signatures;
                    字符串str =迹象[0] .toCharsString();

                    字符串的MD5 = MD5En coder.en code(STR);
                    //将应用程序签名与数据库中保存的签名进行比较,如果相一致,则使病毒数加1,并通过handler在界面显示病毒包名
                    光标光标= db.rawQuery(选择确定时代递减,其中的md5 =?,新的String [] {MD5});
                    如果(cursor.moveToFirst()){
                        desc字符串= cursor.getString(0);
                        味精= Message.obtain();
                        msg.obj = info.packageName +:+说明;
                        _handler.sendMessage(MSG); _
                        virustotal ++;
                    }
                    cursor.close();
                    pb.setProgress(总);

                }
                消息味精= Message.obtain();
                msg.what =停止;
                msg.obj =扫描完毕,共发现+ virustotal +个病毒;
                _handler.sendMessage(MSG); _
                flagscanning = FALSE;
                pb.setProgress(0);
            };
        }。开始();
    }
    返回super.onTouchEvent(事件);
}

@覆盖
保护无效的onDestroy(){
    如果(db.isOpen())
        db.close();
    super.onDestroy();
}

@覆盖
公共布尔onCreateOptionsMenu(功能菜单){
    //充气菜单;这增加了项目操作栏,如果它是present。
    。getMenuInflater()膨胀(R.menu.main,菜单);
    返回true;
}
}
 

解决方案

请您处理一个静态类。

该警告是皮棉警告。您可以禁用警告,但它是一个有用的信息

下面是林特检查清单

http://tool​​s.android.com/tips/lint-checks

从源头@报价

<一个href="http://android-developers.blogspot.in/2009/01/avoiding-memory-leaks.html">http://android-developers.blogspot.in/2009/01/avoiding-memory-leaks.html

避免非静态内部类的活动,如果你不控制自己的生命周期,使用静态内部类,使弱引用里面的活动。

解决这个问题是使用静态内部类与的WeakReference 外部类,如做过的ViewRoot 并以其w内部类的实例。

另外,请在Android开发组的讨论。检查溶液罗曼盖伊

<一个href="https://groups.google.com/forum/#!topic/android-developers/1aPZXZG6kWk">https://groups.google.com/forum/#!topic/android-developers/1aPZXZG6kWk

从罗曼盖伊的从上面的链接的解决方案实例

 类OuterClass {
 类{将InnerClass
  私人最终的WeakReference&LT; OuterClass&GT; mTarget;

   将InnerClass(OuterClass目标){
    mTarget =新的WeakReference&LT; OuterClass&GT;(目标);
  }

  无效DoSomething的(){
  OuterClass目标= mTarget.get();
  如果(目标!= NULL)target.do();
   }
 

编辑:

例如:

 公共类MainActivity延伸活动{

      的LinearLayout LL;
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.activity_main);
        LL =新的LinearLayout(本);
        新HandlerClass(本);
    }
       私有静态类HandlerClass扩展处理程序{
           私人最终的WeakReference&LT; MainActivity&GT; mTarget;
        公共HandlerClass(MainActivity上下文)
        {
             mTarget =新的WeakReference&LT; MainActivity&GT;((MainActivity)上下文);

        }

            @覆盖
            公共无效的handleMessage(信息MSG){
                super.handleMessage(MSG);
                MainActivity目标= mTarget.get();
                如果(目标!= NULL)
                 如果(msg.what == 1){
                     target.ll.removeAllViews();
                    // anim.stop();

                     }
                 字符串str =(字符串)msg.obj;
                 TextView的电视=新的TextView(目标);
                 tv.setText(STR);
                 target.ll.setOrientation(LinearLayout.VERTICAL);
                 target.ll.addView(电视);
                 //sv.scrollBy(0,20);

                的System.out.println(STR);

            }

        };
}
 

纠正我,如果上面是错误的或者有一些问题。

您还可以通过亚历克斯·洛克伍德检查这个博客

<一个href="http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html">http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html

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

解决方案

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

这篇关于这个处理程序类应该是静态的或可能发生泄漏(com.test.test3.ui.MainActivity.1)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆