[英]Good practice for Android services?
我想為我的主要活動創建一個獨立的服務。 該服務在啟動手機時啟動,每隔x分鍾通過網絡服務檢索一次信息。
最佳做法是什么?
以BOOT_COMPLETED操作啟動服務?
還有其他一些動作可以在不啟動主要活動的情況下啟動服務嗎? 另一種設計還是最佳實踐?
例如,我想要一種行為與Facebook相同的服務。 該服務一直處於活動狀態,並在您收到消息時顯示通知。 如果單擊通知,它將打開Facebook應用程序。 但這殺死了應用程序,服務仍然處於活動狀態以接收新消息。
當我想終止主要活動時,我的第一個測試會終止我的服務。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="fr.mrbmx"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<!-- The following two permissions are not required to use
Google Maps Android API v2, but are recommended. -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="fr.mr.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="fr.mr.service.MyReceiver"
android:enabled="true"
android:exported="false"
android:label="OnBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service
android:name="fr.mr.service.LocalService"
android:enabled="true"
android:exported="false"
android:label="LocalService" />
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="@string/mapKey"/>
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
</application>
public class MyReceiver extends BroadcastReceiver {
private static final String TAG = MyReceiver.class.getName();
@Override
public void onReceive( Context ctx, Intent i ) {
Log.d( TAG, "MyReceiver.onReceive : " + i.getAction() );
ctx.startService(new Intent().setComponent(new ComponentName(
ctx.getPackageName(), LocalService.class.getName())));
}
}
public class LocalService extends Service{
private static final String TAG = LocalService.class.getName();
private NotificationManager mNM;
// Unique Identification Number for the Notification.
// We use it on Notification start, and to cancel it.
private int NOTIFICATION = 1332;
private Timer timer ;
private int mId;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
Log.i(TAG, "onCreate");
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
timer = new Timer();
Notification note = new Notification( 0, null, System.currentTimeMillis() );
note.flags |= Notification.FLAG_NO_CLEAR;
startForeground( 0, note );
/*
Notification.Builder mBuilder =
new Notification.Builder(this)
.setSmallIcon(android.R.drawable.ic_dialog_info)
.setContentTitle("test title")
.setContentText("test content")
.setAutoCancel(true)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
startForeground(1, mBuilder.getNotification());*/
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Received start id " + startId + ": " + intent);
mId = startId;
new Thread(new Runnable() {
public void run() {
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
showNotification();
}
}, 0, 60000);
}
}).start();
return START_STICKY;
}
@Override
public void onDestroy() {
Log.i(TAG, "onDestroy");
mNM.cancel(NOTIFICATION);
}
/**
* Show a notification while this service is running.
*/
private void showNotification() {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(android.R.drawable.ic_dialog_info)
.setContentTitle(getString(fr.mrbmx.R.string.notification_title))
.setContentText(getString(fr.mrbmx.R.string.notification_text))
.setAutoCancel(true)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(this, MainActivity.class);
// The stack builder object will contain an artificial back stack for the
// started Activity.
// This ensures that navigating backward from the Activity leads out of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(MainActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(mId, mBuilder.build());
}
}
您的服務不需要一直處於活動狀態才能接收消息。 Facebook與幾乎所有其他基於推送的系統一起,使用Google Cloud Messaging(GCM)喚醒您的設備,並從遠程服務器向您的應用程序發送消息。
當然,如果您只需要定期檢查(而不是近乎實時地推送信息),則可以安排警報以每X分鍾啟動一次服務,或構建一個同步適配器 -一個專門用於定期加載數據的Android組件從遠程服務器。
請注意,許多應用程序結合了這兩種方法並運行同步適配器以響應GCM推送 。
我想為我的主要活動創建一個獨立的服務。 該服務在啟動手機時啟動,每隔x分鍾通過網絡服務檢索一次信息。
當然,您可以通過在響應於BOOT_COMPLETED
AndroidManifest.xml
上注冊BroadcastReceiver
並BOOT_COMPLETED
啟動Service
來做到這一點。 您的應用必須至少運行一次才能交付BOOT_COMPLETED
(在API 11之前不是這種情況)。 另外,請考慮過分頻繁地從服務器提取數據的含義(例如電池等)。
例如,我想要一種行為與facebook相同的服務。 該服務一直處於活動狀態,並在您收到消息時顯示通知。 如果單擊硝化,它將打開facebook應用程序。 但這殺死了應用程序,服務仍然處於活動狀態以接收新消息。
至少對於他們的聊天應用程序,Facebook使用MQTT,它是一種M2M發布/訂閱異步機制。 他們不會每隔X分鍾從服務器提取數據。 他們只是在廣播時監聽傳入的數據。 如果您想使用MQTT,您可能會對一個名為Eclipse Paho
開源項目感興趣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.