问题描述
我是新来的Android和我尝试开发一个系统,但是当我完成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://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
从罗曼盖伊的从上面的链接的解决方案实例
类OuterClass {
类{将InnerClass
私人最终的WeakReference< OuterClass> mTarget;
将InnerClass(OuterClass目标){
mTarget =新的WeakReference< OuterClass>(目标);
}
无效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< MainActivity> mTarget;
公共HandlerClass(MainActivity上下文)
{
mTarget =新的WeakReference< MainActivity>((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);
}
};
}
纠正我,如果上面是错误的或者有一些问题。
您还可以通过亚历克斯·洛克伍德检查这个博客
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)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!