从小部件中的onDeleted方法调用handler.removeCallbacks会引发nullpointerexception [英] Calling handler.removeCallbacks from onDeleted method in a widget throws a nullpointerexception

查看:97
本文介绍了从小部件中的onDeleted方法调用handler.removeCallbacks会引发nullpointerexception的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当用户删除窗口小部件时,我需要停止处理程序,但是调用handler.removeCallbacks会从onDeleted方法中引发nullpointerexception.我尝试了其他变通方法,例如在实现runnable的类中创建方法来杀死该runnable,但这也会引发nullpointerexception.
也许在调用onDeleted方法之后处理程序会变为null,所以我尝试将其放在onDisabled方法中,但没有停止.
我在做什么错了?

I need to stop the handler when the widget is removed by the user but calling handler.removeCallbacks throws a nullpointerexception from the onDeleted method. I tried other workarounds like creating a method,in a class which implements runnable, to kill the runnable but this throw a nullpointerexception also.
Maybe handler gets null after the call of the onDeleted method so I tried to put it in the onDisabled method but nothing stop.
What am I doing wrong?

代码在这里:

public class RAMWidget extends AppWidgetProvider {

private PieGraph pg;
private Context context;
private RemoteViews remoteViews;
private AppWidgetManager appWidgetManager;
private ComponentName widget;
private Handler handler;
private CustomRunnable runnable;

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
{
    this.context=context;
    this.appWidgetManager=appWidgetManager;
    remoteViews=new RemoteViews(context.getPackageName(),R.layout.widget_ram);
    widget=new ComponentName(context,RAMWidget.class);
    new DrawTask().execute();
    handler=new Handler();
    runnable=new CustomRunnable();
    handler.postDelayed(runnable,3000);
}

private class CustomRunnable implements Runnable
{
    private boolean stop;

    public CustomRunnable()
    {
        stop=false;
    }

    @Override
    public void run()
    {
         new DrawTask().execute();
         Log.i("STOP",stop+"");
         if(!stop)
            handler.postDelayed(this,3000);
         else
            return;
         Log.i("STOP",stop+"");
    }

    void killThread()
    {
        stop=true;
    }
}

private class DrawTask extends AsyncTask<Void,Void, Void>
{
    private PieSlice slice,_slice;
    private long total=0,free=0,rate=0;

    @Override
    protected Void doInBackground(Void... unused)
    {
        RandomAccessFile reader=null;
        try
        {
            reader=new RandomAccessFile("/proc/meminfo","r");
            long[] mems=new long[4];
            for(int i=0;i<4;i++)
            {
                String load = reader.readLine();
                String[] toks = load.split(":");
                mems[i] = Long.parseLong(toks[1].replace("kB","").trim());
            }
            total=mems[0]/1024;
            free=(mems[1]+mems[2]+mems[3])/1024;
            rate=(int)((float)(total-free)/total*100);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        if(reader!=null)
            try
            {
                reader.close();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        slice=new PieSlice();
        slice.setTitle("Available RAM");
        slice.setColor(Color.parseColor("#99CC00"));
        slice.setValue(total-free);
        _slice=new PieSlice();
        _slice.setTitle("Used RAM");
        _slice.setColor(Color.parseColor("#FFBB33"));
        _slice.setValue(free);
        publishProgress();
        return null;
    }

    @Override
    protected void onProgressUpdate(Void... values)
    {
        pg=new PieGraph(context);
        pg.measure(200,200);
        pg.layout(0,0,200,200);
        pg.setDrawingCacheEnabled(true);
        pg.addSlice(slice);
        pg.addSlice(_slice);
        pg.setInnerCircleRatio(150);
        for (PieSlice s : pg.getSlices())
            s.setGoalValue(s.getValue());
        pg.setDuration(1000);
        pg.setInterpolator(new AccelerateDecelerateInterpolator());
        pg.animateToGoalValues();
        pg.setPadding(3);
        remoteViews.setTextViewText(R.id.widget_ram_text, "Total RAM " + total + " MB");
        remoteViews.setTextViewText(R.id.widget_ram_text1,"Avaiable RAM "+(total-free)+" MB");
        remoteViews.setTextViewText(R.id.widget_ram_text2,"Used RAM "+free+" MB");
        Bitmap bitmap=pg.getDrawingCache();
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.BLACK);
        paint.setTextSize(18);
        paint.setShadowLayer(1f,0f,1f,Color.WHITE);
        Rect bounds=new Rect();
        paint.getTextBounds(rate+" %",0,new String(rate+" %").length(),bounds);
        int x=(bitmap.getWidth()-bounds.width())/2;
        int y=(bitmap.getHeight()+bounds.height())/2;
        canvas.drawText(rate+" %",x,y,paint);
        remoteViews.setImageViewBitmap(R.id.graph_widget,bitmap);
        appWidgetManager.updateAppWidget(widget,remoteViews);
    }
  }

  @Override
  public void onDeleted(Context context, int[] appWidgetIds) {
      runnable.killThread();
      handler.removeCallbacks(runnable);       //both of them don't work
      super.onDeleted(context, appWidgetIds);
  }

  @Override
  public void onDisabled(Context context) {
      runnable.killThread();
      handler.removeCallbacks(runnable);
      super.onDisabled(context);
  }
}

推荐答案

问题是您不能每次都依赖Android调用的同一个窗口小部件实例,因此将非静态字段保留在窗口小部件中提供者是个问题.

The problem is that you can't depend on the same instance of your widget being called by Android each time, and so keeping non-static fields in your widget provider is a problem.

一个简单的解决方案是将静态字段用于处理程序和可运行.看起来其他一些字段也可能消失,例如,每次调用onProgressUpdate时都会构造PieGraph,因此它可以是本地的.基本上,应避免在小部件中使用所有非静态字段.

An easy solution would be to use static fields for handler and runnable. It looks like some of the other fields could go away too, for example PieGraph is constructed each time onProgressUpdate is called, so it could be a local. Basically you should avoid all non-static fields in a widget.

这篇关于从小部件中的onDeleted方法调用handler.removeCallbacks会引发nullpointerexception的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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