2013-01-24 26 views
2

我正在設計我的第一個Android應用程序。我需要什麼樣的服務?自定義IntentService?

這個應用程序在幾個Runnable做一些東西。最初我讓這個Runnable由一個Thread(每個Runnable的一個線程)執行。每個Runnable也是可觀察的,所以它可以通知對活動的更改。用戶點擊一個開始按鈕,一個或多個Runnable開始,他們在執行期間通知gui,然後停止。一切正常。

第一個問題:這種方法是正確的嗎?爲了回答這個問題,請繼續閱讀。

我需要在我的應用程序的其他兩件事情:

  1. ,以確保我的工作的執行不會停止,即使用戶從我的應用程序做別的事情消失;
  2. 來規劃我的Runnable的執行,它必須在後臺啓動和執行。例如:用戶決定要在16:00每天執行一項「工作」。

我見過我可以用AlarmManager和Service來做到這一點。

第二個問題:我需要一個可以異步管理幾個Runnable的服務,所以當AlarmManager啓動時我要求這個服務來完成請求的工作;我還將修改應用程序的第一部分:而不是線程我將使用此服務,所以我可以確保執行不會停止。 我需要什麼樣的服務? IntentService可以完成這項工作嗎? 以這種方式進行是正確的嗎?有更好的解決方案?

你能舉一些我能如何實現這一切的例子嗎?

我希望我能清楚地解釋我的情況,否則我會盡力做得更好。

問候

回答

0

第一個問題:是這種做法是正確的?

不,你應該實現在Thread S IN一個Service運行Runnable秒。

如果您不需要Service同時處理多個請求,則IntentService將是您的最佳選擇。如果您啓動Service,它將繼續在後臺運行,即使啓動它的Activity進入後臺或停止。

A Runnable s可以發送指示需要UI更新的廣播。 Activity應該註冊BroadcastReceiver以收聽廣播消息並相應地更新UI。

您可以使用AlarmManager按照您的指示安排作業的執行。一種方法是安排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> 
相關問題