1

以下消息处理程序可以正常接收来自我的服务的消息...

private  Handler handler = new Handler() 
{

    public void handleMessage(Message message) 
    {
        Object path = message.obj;

        if (message.arg1 == 5 && path != null)  //5 means its a single mapleg to plot on the map
        {
            String myString = (String) message.obj;
            Gson gson = new Gson();
            MapPlot mapleg = gson.fromJson(myString, MapPlot.class);
            myMapView.getOverlays().add(new DirectionPathOverlay(mapleg.fromPoint, mapleg.toPoint));
            mc.animateTo(mapleg.toPoint);

        }
        else
        {
            if (message.arg1 == RESULT_OK && path != null) 
            {
                Toast.makeText(PSActivity.this, "Service Started" + path.toString(), Toast.LENGTH_LONG).show();
            } 
            else 
            {
                Toast.makeText(PSActivity.this,"Service error" + String.valueOf(message.arg1),  Toast.LENGTH_LONG).show();          


            }

        }
    };
};

然而,即使它在 AVD 中测试正常(我通过 DDMS 向它提供了一个大的 KML 文件)“对象路径 = message.obj;” 行有一个警告说“这个处理程序类应该是静态的,否则可能会发生泄漏”。

但是如果我说“static Handler handler = new Handler()”,它不会编译并抱怨我“不能对非静态字段 myMapView 进行静态引用。如果我不能进行这样的引用,我就做不到任何有用的东西。

这让我在这个问题上花了几个小时在谷歌上搜索,并且比我想知道的更多地了解弱引用。我发现经常发现的建议是我应该更换......

private Handler handler = new Handler()

   static class handler extends Handler
{
    private final WeakReference<PSActivity> mTarget;
    handler(PSActivity target)
    {
        mTarget = new WeakReference<PSActivity>(target);
    }

但这不会编译仍然抱怨我无法对非 dtatic 字段进行静态引用。所以,我一周或之前的问题是“我怎样才能为 android 编写一个消息处理程序,以便我的服务可以将数据发送到我的活动。即使我有工作代码,问题仍然与后缀“不泄漏内存”有关。谢谢,加里

4

2 回答 2

5

当我尝试在服务中使用处理程序时,我收到了相同的警告消息,并最终通过从这个线程中获取建议来解决它,请参阅我项目中的代码片段。

public class MyService extends Service {
    ...
    private MyHandler mHandler;

    public static class MyHandler extends Handler {
        private final WeakReference<MyService> mService;

        MyHandler(MyService service) {
            mService = new WeakReference<MyService>(service);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            MyService service = mService.get();
            if (service!=null) {
                if (msg.what==MSG_RESUME_CHECKING) {
                    service.pause();
                } else if (msg.what==MSG_PAUSE_CHECKING) {
                    service.resume();
                }
            }
        }
    }
    ...

    @Override
    public void onCreate() {
        super.onCreate();
        ...
        mHandler = new MyHandler(this);
        ...
    }
}
于 2012-10-17T04:06:31.287 回答
0

我知道我参加聚会有点晚了,但希望这有助于进一步回答未来询问者的问题。

正如您通过谷歌搜索发现的那样(我自己做了很多事情来解决类似的问题),您需要将 Handler 实例转换为静态内部类(嵌套类),该类在其构造函数中采用目标 Activity。然后它将这个 Activity 引用转换为 WeakReference,这就是可以用来与目标 Activity 中的事物交互的东西。在你的情况下:

Toast.makeText(mTarget.get().this, "Service Started" + path.toString(), Toast.LENGTH_LONG).show();

由于您要更改为嵌套类,因此您还需要创建该类的实例,以便您的 Thread 在其 run() 方法中访问。有关这方面的更多帮助(以及如何确保您的应用即使在配置更改后也能正常工作),请参阅此问题

希望这可以帮助!

于 2014-10-23T03:46:39.183 回答