0

Androidでホームスクリーンウィジェットを作成しています。ウィジェット プロバイダーは、5 分ごとにウィジェットを更新するサービスを開始します。ホーム画面からウィジェットを削除すると、ウィジェット プロバイダーの「onDisabled()」メソッドでサービスがキャンセルされます。しかし、サービスは null であり、サービスはバックグラウンドで永久に実行され続けます! これが null である理由がわかりません。これを行う方法のアイデアはありますか? また、すべてのウィジェット インスタンスに対して 1 つのサービス インスタンスを使用できますか?

私のウィジェットプロバイダー

    public class MyWidgetProvider extends AppWidgetProvider {

    private PendingIntent service = null;

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
            int[] appWidgetIds) {
        final AlarmManager m = (AlarmManager) context
                .getSystemService(Context.ALARM_SERVICE);

        final Calendar TIME = Calendar.getInstance();
        TIME.set(Calendar.MINUTE, 0);
        TIME.set(Calendar.SECOND, 0);
        TIME.set(Calendar.MILLISECOND, 0);

        final Intent i = new Intent(context, UpdatorService.class);

        i.putExtra("WIDGET_IDS", appWidgetIds);

        if (service == null) {
            service = PendingIntent.getService(context, 0, i,
                    PendingIntent.FLAG_UPDATE_CURRENT);
        }

        m.setRepeating(AlarmManager.RTC, TIME.getTime().getTime(), 60 * 1000,
                service);

        super.onUpdate(context, appWidgetManager, appWidgetIds);
    }

    @Override
    public void onDisabled(Context context) {

        final AlarmManager m = (AlarmManager) context
                .getSystemService(Context.ALARM_SERVICE);
        Log.d("onDisabled() >>> ", service + "");
        if (service != null) {
            Log.d("WIDGET>>>", "Cancelling the service");
            m.cancel(service);
            service.cancel();
        }
    }
}

アップデータサービス

 public class UpdatorService extends Service {
    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        int[] widgetIds = (int[]) intent.getExtras().get("WIDGET_IDS");
        for (int i = 0; i < widgetIds.length; i++) {
            SharedPreferences prefs = getSharedPreferences("PREFS_"
                    + widgetIds[i], Context.MODE_PRIVATE);
            if (prefs != null) {
                //something logic here

                               //This is a async task to get http data
                new RequestTask(this, parameterMap, widgetIds[i]).execute();

            }
        }
        return START_NOT_STICKY;
    }

    private void buildUpdate(int widgetId, String result) {
        ChartRenderer ch = new ChartRenderer();
        GraphicalView gview=ch.generateChart(result, this);
        RemoteViews views = new RemoteViews(getPackageName(),
                R.layout.bw_widget_layout);
        views.setBitmap(R.id.chart, "setImageBitmap", ch.getBitmapFromView(gview));

        AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this);
        appWidgetManager.updateAppWidget(widgetId, views);

    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    public void processResult(String result, int widgetId) {
        buildUpdate(widgetId, result);

    }

}

リクエストタスク

 class RequestTask extends AsyncTask<String, String, String> {

    private UpdatorService service;
    private Map<String, String> paramMap;
    int widgetId;

    RequestTask(UpdatorService service, Map<String, String> paramMap, int wid) {
        this.service = service;
        this.paramMap = paramMap;
        widgetId = wid;

    }

    @Override
    protected String doInBackground(String... uri) {

        .......

        return responseString;

    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        service.processResult(result, widgetId);
    }

}
4

1 に答える 1

1

まず第一に、サービスを RequestTask に渡すべきではありません。これは悪い設計です。

Intent を使用してプロバイダーに更新を送信する必要があります。サンプル ウィジェットを見ると、同じ動作をしています。また、サービスの記述が不十分です。作業が終了したら、アプリケーションから停止するのではなく、すぐに停止する必要があります。より効率的で、サービス状態のメンテナンスがよりクリーンです

サービスの全体的なアイデアはこれです(あなたの場合):

作業を行ってから停止する

フロー

Intent リクエストは処理を行うサービスを開始し、Intent Extras を介して情報を渡し、ウィジェットにその魔法を実行させてから、ウィジェット自体を停止し、責任を持って を呼び出し<service>.stopSelf()ます。

于 2013-10-11T05:29:41.010 に答える