編輯:關於Android編程
A Service is an application component representing either an application's desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use. Each service class must have a corresponding給大家蹩腳的翻譯一下: Service是一個應用組件,代表著:“在不和用戶交互的情況下,進行‘持續’運行的應用需求”或者“為其他應用提供功能性服務” 。每個Service類(當然是你要用的)都需要在Manifest文件中聲明(利用declaration in its package's AndroidManifest.xml. Services can be started with Context.startService() andContext.bindService(). Note that services, like other application objects, run in the main thread of their hosting process. This means that, if your service is going to do any CPU intensive (such as MP3 playback) or blocking (such as networking) operations, it should spawn its own thread in which to do that work. More information on this can be found in Processes and Threads. The IntentService class is available as a standard implementation of Service that has its own thread where it schedules its work to be done.
? A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of. ? A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors).Service不是一個分隔獨立的進程 Service不是線程,不代表它脫離主線程工作 把兩點合一起:service是運行在啟動它的應用程序進程中的,應用程序這個進程有主線程(俗稱UI線程),service不脫離主線程工作,所以你不能阻塞service的主線程,否則這會帶來ANR。 我們先不看生命周期(其實大家對此是比較明白的) 我們看API中提到的Local Service使用,順便引出一個疑惑。 寫一個Service:
public class LocalService extends Service { private NotificationManager mNM; // Unique Identification Number for the Notification. // We use it on Notification start, and to cancel it. private int NOTIFICATION = R.string.local_service_started; /** * Class for clients to access. Because we know this service always * runs in the same process as its clients, we don't need to deal with * IPC. */ public class LocalBinder extends Binder { LocalService getService() { return LocalService.this; } } @Override public void onCreate() { mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); // Display a notification about us starting. We put an icon in the status bar. showNotification(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i("LocalService", "Received start id " + startId + ": " + intent); // We want this service to continue running until it is explicitly // stopped, so return sticky. return START_STICKY; } @Override public void onDestroy() { // Cancel the persistent notification. mNM.cancel(NOTIFICATION); // Tell the user we stopped. Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show(); } @Override public IBinder onBind(Intent intent) { return mBinder; } // This is the object that receives interactions from clients. See // RemoteService for a more complete example. private final IBinder mBinder = new LocalBinder(); /** * Show a notification while this service is running. */ private void showNotification() { // In this sample, we'll use the same text for the ticker and the expanded notification CharSequence text = getText(R.string.local_service_started); // Set the icon, scrolling text and timestamp Notification notification = new Notification(R.drawable.stat_sample, text, System.currentTimeMillis()); // The PendingIntent to launch our activity if the user selects this notification PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, LocalServiceActivities.Controller.class), 0); // Set the info for the views that show in the notification panel. notification.setLatestEventInfo(this, getText(R.string.local_service_label), text, contentIntent); // Send the notification. mNM.notify(NOTIFICATION, notification); } }
private LocalService mBoundService; private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { // This is called when the connection with the service has been // established, giving us the service object we can use to // interact with the service. Because we have bound to a explicit // service that we know is running in our own process, we can // cast its IBinder to a concrete class and directly access it. mBoundService = ((LocalService.LocalBinder)service).getService(); // Tell the user about this for our demo. Toast.makeText(Binding.this, R.string.local_service_connected, Toast.LENGTH_SHORT).show(); } public void onServiceDisconnected(ComponentName className) { // This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed. // Because it is running in our same process, we should never // see this happen. mBoundService = null; Toast.makeText(Binding.this, R.string.local_service_disconnected, Toast.LENGTH_SHORT).show(); } }; void doBindService() { // Establish a connection with the service. We use an explicit // class name because we want a specific service implementation that // we know will be running in our own process (and thus won't be // supporting component replacement by other applications). bindService(new Intent(Binding.this, LocalService.class), mConnection, Context.BIND_AUTO_CREATE); mIsBound = true; } void doUnbindService() { if (mIsBound) { // Detach our existing connection. unbindService(mConnection); mIsBound = false; } } @Override protected void onDestroy() { super.onDestroy(); doUnbindService(); }
Disconnect from an application service. You will no longer receive calls as the service is restarted, and the service is now allowed to stop at any time.斷開應用服務連接,你不會再收到service重啟的消息(回調),這個service也可以在任意時間被系統終止了。 這裡我們做一個簡單的測試,讓兩個Activity綁定同一個Service,看解除綁定對service的影響:
package com.example.testservice; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; public class MainActivity extends Activity { private final static String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "onCreate"); doBindService(); findViewById(R.id.button).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub startActivity(new Intent(MainActivity.this,SecondActivity.class)); } }); } private LocalService mBoundService; private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { mBoundService = ((LocalService.LocalBinder)service).getService(); // Tell the user about this for our demo. Log.d(TAG, "service bind"); } public void onServiceDisconnected(ComponentName className) { // This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed. // Because it is running in our same process, we should never // see this happen. mBoundService = null; Log.d(TAG, "service unbind"); } }; void doBindService() { // Establish a connection with the service. We use an explicit // class name because we want a specific service implementation that // we know will be running in our own process (and thus won't be // supporting component replacement by other applications). Log.d(TAG, "do service bind"); bindService(new Intent(this, LocalService.class), mConnection, Context.BIND_AUTO_CREATE); mIsBound = true; } private boolean mIsBound = false; void doUnbindService() { if (mIsBound) { // Detach our existing connection. Log.d(TAG, "do service unbind"); unbindService(mConnection); mIsBound = false; } else { Log.d(TAG, "no necessary to unbind,it is not binding"); } } @Override protected void onDestroy() { Log.d(TAG, "onDestroy"); super.onDestroy(); doUnbindService(); } }
package com.example.testservice; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.util.Log; public class SecondActivity extends Activity { private final static String TAG = "SecondActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); doBindService(); } private LocalService mBoundService; private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { mBoundService = ((LocalService.LocalBinder)service).getService(); // Tell the user about this for our demo. Log.d(TAG, "service bind"); } public void onServiceDisconnected(ComponentName className) { // This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed. // Because it is running in our same process, we should never // see this happen. mBoundService = null; Log.d(TAG, "service unbind"); } }; void doBindService() { // Establish a connection with the service. We use an explicit // class name because we want a specific service implementation that // we know will be running in our own process (and thus won't be // supporting component replacement by other applications). Log.d(TAG, "do service bind"); bindService(new Intent(this, LocalService.class), mConnection, Context.BIND_AUTO_CREATE); mIsBound = true; } private boolean mIsBound = false; void doUnbindService() { if (mIsBound) { // Detach our existing connection. Log.d(TAG, "do service unbind"); unbindService(mConnection); mIsBound = false; } else { Log.d(TAG, "no necessary to unbind,it is not binding"); } } @Override protected void onDestroy() { Log.d(TAG, "onDestroy"); super.onDestroy(); doUnbindService(); } }
package com.example.testservice; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; /** * @ClassName: LocalService * @Description: TODO * @date 2016年4月27日 下午3:43:57 * * @author leobert.lan * @version 1.0 */ public class LocalService extends Service { private final static String TAG = "LocalService"; /** * Class for clients to access. Because we know this service always * runs in the same process as its clients, we don't need to deal with * IPC. */ public class LocalBinder extends Binder { LocalService getService() { return LocalService.this; } } @Override public void onCreate() { Log.i(TAG, "service onCreate"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG, "Received start id " + startId + ": " + intent); // We want this service to continue running until it is explicitly // stopped, so return sticky. return START_STICKY; } @Override public void onDestroy() { Log.i(TAG, "service destroy"); super.onDestroy(); } @Override public IBinder onBind(Intent intent) { Log.i(TAG, "service onBind"); return mBinder; } // This is the object that receives interactions from clients. See // RemoteService for a more complete example. private final IBinder mBinder = new LocalBinder(); }我截取了一下logcat,但是eclipse的背景。。。
// This is called when the connection with the service has been // established, giving us the service object we can use to // interact with the service. Because we have bound to a explicit // service that we know is running in our own process, we can // cast its IBinder to a concrete class and directly access it.bindService可以獲得service對象,並且和它進行交互(說白了就是想調用他的方法)。 我們還有另外一個有逼格的東西:IntentService。
IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work. This "work queue processor" pattern is commonly used to offload tasks from an application's main thread. The IntentService class exists to simplify this pattern and take care of the mechanics. To use it, extend IntentService and implement onHandleIntent(Intent). IntentService will receive the Intents, launch a worker thread, and stop the service as appropriate. All requests are handled on a single worker thread -- they may take as long as necessary (and will not block the application's main loop), but only one request will be processed at a time.IntentService是service的子類,設計用來處理異步請求,通過startService函數的調用來發送請求,吧啦吧啦一堆。 要使用它的話需要實現onHandlerIntent方法,這個方法的描述:
This method is invoked on the worker thread with a request to process. Only one Intent is processed at a time, but the processing happens on a worker thread that runs independently from other application logic. So, if this code takes a long time, it will hold up other requests to the same IntentService, but it will not hold up anything else. When all requests have been handled, the IntentService stops itself, so you should not call stopSelf().Intent是有序到達、處理的,先來的先處理,耗時的話後面的等著,不會阻塞主線程之類的,干完活自己干死自己,所以你不要調用stopSelf(). 然而我們經常覺得沒啥卵用。
一. Application用途 1. Application用途 創建Application時機 : Application在啟動的時候會調用Application
引言最近在工作中由於需要客制化系統的關系,接觸到了很多ViewPager相關的UI,發現很多底層原生的界面也還是依然采用ViewPager+Fragment的布局方式,事
2月下旬辭職了,去海南度假到現在,領略了一把三亞風情也算任性和然而這樣任性帶來的後果就是。。不行了我必須吐槽一句。。沒畢業的找工作就這麼難嘛!投了57家一家面試機會都沒有
GradientDrawable可以在res/drawable目錄下以xml文件用標簽來定義。看看官方文檔給出的xml定義說明吧。