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 ファイルをフィードしている) で問題なくテストできますが、「object path = message.obj;」行には、「この Handler クラスは静的である必要があります。そうしないと、リークが発生する可能性があります」という警告があります。

しかし、「static Handler handler = new Handler()」と言うと、「非静的フィールド myMapView への静的参照を作成できない」と不平を言ってコンパイルされません。そのような参照を作成できない場合は、できません便利なもの。

これにより、この問題について数時間グーグルで調べ、weakReferencesについて知りたいと思っていたよりも多くのことを学びました. 私が見つけたよくある推奨事項は、交換する必要があるということです...

private Handler handler = new Handler()

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

しかし、これはまだコンパイルされず、非 dtatic フィールドへの静的参照を作成できないと不平を言っています。そのため、1週間前または1週間前の私の質問は、「サービスがアクティビティにデータを送信できるように、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

私はパーティーに少し遅れていることを知っていますが、これが将来の質問者の質問にさらに答えるのに役立つことを願っています.

グーグルで発見したように(同様の問題を解決するために私がかなりのことをしたことです)、ハンドラインスタンスを静的な内部クラス(ネストされたクラス)に変換する必要があります。次に、この Activity 参照を WeakReference に変換します。これを使用して、ターゲット Activity 内のものを操作できます。あなたの場合:

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

ネストされたクラスに変更しているため、スレッドがその run() メソッドでアクセスできるように、そのクラスのインスタンスも作成する必要があります。これに関する詳細なヘルプ (構成の変更後もアプリが動作することを確認する方法と同様) については、この質問を参照してください。

お役に立てれば!

于 2014-10-23T03:46:39.183 に答える