2

初めての Android アプリを設計しています。

このアプリは、いくつかのことを行う複数の Runnable で構成されています。最初に、この Runnable をスレッド (各 Runnable のスレッド) によって実行されるようにしました。各 Runnable は Observable でもあるため、Activity への変更を通知できます。ユーザーが開始ボタンをクリックすると、1 つ以上の Runnable が開始され、実行中に GUI に通知するジョブが実行されてから停止します。すべて正常に動作します。

最初の質問: そのアプローチは正しいですか? この質問に答えるために、読み続けてください。

アプリには他に 2 つのものが必要です。

  1. ユーザーがアプリから離れて何か他のことをしたとしても、ジョブの実行が停止しないようにするため。
  2. バックグラウンドで開始して実行する必要がある Runnable の実行を計画します。例: ユーザーは、「ジョブ」を毎日 16:00 に実行することを決定します。

AlarmManager と Service を使用してそれを実行できることを確認しました。

2 番目の質問: 複数の Runnable を非同期で管理できる Service が必要なので、AlarmManager の開始時に、この Service に要求されたジョブを実行するように依頼します。アプリケーションの最初の部分も変更します。スレッドの代わりにこのサービスを使用するので、実行が停止しないことを確認できます。どのようなサービスが必要ですか? IntentServiceはこの仕事をすることができますか? このままでいいのでしょうか?より良い解決策はありますか?

それをすべて実装する方法の例を教えてください。

自分の状況を明確に説明できればと思います。

よろしく

4

1 に答える 1

0

最初の質問: そのアプローチは正しいですか?

Runnableいいえ、 s in Threads in aを実装して実行する必要がありますService

複数のリクエストを同時に処理するIntentService必要がない場合は、 が最適なオプションです。Serviceを起動すると、起動した がバックグラウンドに移動したり停止したりしてServiceも、バックグラウンドで実行され続けます。Activity

は、UIのRunnable更新が必要であることを示すブロードキャストを送信できます。はActivityを登録BroadcastReceiverしてブロードキャスト メッセージをリッスンし、それに応じて UI を更新する必要があります。

を使用して、AlarmManager指定したとおりにジョブの実行をスケジュールできます。 これを行う 1 つの方法は、適切なジョブを実行することによって動作するAlarmManager、ブロードキャストを送信して が受信するようにスケジュールすることです。IntentService

これらすべてを組み合わせた例を次に示します。

こちらがIntentService

public class MyIntentService extends IntentService {
    public static final String ACTION_START_JOB = "com.mycompany.myapplication.START_JOB";
    public static final String ACTION_UPDATE_UI = "com.mycompany.myapplication.UPDATE_UI";

    private final IBinder mBinder = new MyBinder();

    // You can have as many Runnables as you want.
    Runnable run = new Runnable() {
        @Override
        public void run() {
            // Code to run in this Runnable.
            // If the code needs to notify an Activity
            // for a UI update, it will send a broadcast.
            Intent intent = new Intent(ACTION_UPDATE_UI);
            sendBroadcast(intent);
        }
    };

    public MyIntentService() {
        super("MyIntentService");
    }

    @Override
    public void onCreate() {
        // You need to register your BroadcastReceiver to listen
        // to broadcasts made by the AlarmManager.
        // The BroadcastReceiver will fire up your jobs when these
        // broadcasts are received.
        IntentFilter filter = new IntentFilter(ACTION_START_JOB);
        registerReceiver(jobBroadcastReceiver, filter);
    }

    @Override
    public void onDestroy() {
        // You should unregister the BroadcastReceiver when
        // the Service is destroyed because it's not needed
        // any more.
        unregisterReceiver(jobBroadcastReceiver);
    }

    /**
     * This method is called every time you start this service from your
     * Activity. You can Spawn as many threads with Runnables as you want here.
     * Keep in mind that your system have limited resources though.
     */
    @Override
    protected void onHandleIntent(Intent intent) {
        Intent intentFireUp = new Intent();
        intentFireUp.setAction(ACTION_START_JOB);
        PendingIntent pendingIntentFireUpRecording = PendingIntent
                .getBroadcast(MyIntentService.this, 0, intentFireUp, 0);

        AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

        Calendar cal = Calendar.getInstance();

        int year = 2013, month = 5, day = 10, hourOfDay = 7, minute = 13, second = 0;

        cal.set(year, month, day, hourOfDay, minute, second);
        long startTime = cal.getTimeInMillis() + 5 * 60 * 1000; // starts 5
                                                                // minutes from
                                                                // now
        long intervalMillis = 24 * 60 * 60 * 1000; // Repeat interval is 24
                                                    // hours (in milliseconds)

        // This alarm will send a broadcast with the ACTION_START_JOB action
        // daily
        // starting at the given date above.
        alarm.setRepeating(AlarmManager.RTC_WAKEUP, startTime, intervalMillis,
                pendingIntentFireUpRecording);

        // Here we spawn one Thread with a Runnable.
        // You can spawn as many threads as you want.
        // Don't overload your system though.
        new Thread(run).run();
    }

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

    // Depending on your implementation, you may need to bind
    // to this Service to run one of its methods or access
    // some of its fields. In that case, you will need a Binder
    // like this one.
    public class MyBinder extends Binder {
        MyIntentService getService() {
            return MyIntentService.this;
        }
    }

    // Spawns a Thread with Runnable run when a broadcast message is received.
    // You may need different BroadcastReceivers that fire up different jobs.
    BroadcastReceiver jobBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            new Thread(run).run();
        }
    };

}

そして、これがActivity

public class MyActivity extends Activity {
    Service mService;
    boolean mBound = false;
    ToggleButton mButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mButton = (ToggleButton) findViewById(R.id.recordStartStop);

        mButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                if (mButton.isChecked()) {
                    Intent intent = new Intent(MyActivity.this,
                            MyIntentService.class);
                    startService(intent);
                }
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onResume() {
        super.onResume();
        IntentFilter filter = new IntentFilter(MyIntentService.ACTION_UPDATE_UI);
        registerReceiver(uiUpdateBroadcastReceiver, filter);
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(uiUpdateBroadcastReceiver);
    }

    BroadcastReceiver uiUpdateBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // Here goes the code to update your User Interface
        }
    };

    ServiceConnection myServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            mService = null;
            mBound = false;
        }

        // If you need
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            MyIntentService mService = ((MyBinder) service).getService();
            mBound = true;
        }
    };
}

ファイルにService定義を追加することを忘れないでください。AndroidManifest.xml

<manifest ... >
  ...
  <application ... >
      <service android:name=".MyIntentService" />
      ...
  </application>
</manifest>
于 2013-03-27T03:59:38.643 に答える