欧美三级国产三级日韩三级_亚洲熟妇丰满大屁股熟妇_欧美亚洲成人一区二区三区_国产精品久久久久久模特

android學(xué)習(xí)十八(Service服務(wù)的基本用法) - 新聞資訊 - 云南小程序開發(fā)|云南軟件開發(fā)|云南網(wǎng)站建設(shè)-昆明葵宇信息科技有限公司

159-8711-8523

云南網(wǎng)建設(shè)/小程序開發(fā)/軟件開發(fā)

知識

不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價值,我們在追求其視覺表現(xiàn)的同時,更側(cè)重于功能的便捷,營銷的便利,運營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序為后期升級提供便捷的支持!

您當前位置>首頁 » 新聞資訊 » 技術(shù)分享 >

android學(xué)習(xí)十八(Service服務(wù)的基本用法)

發(fā)表時間:2020-10-19

發(fā)布人:葵宇科技

瀏覽次數(shù):36


     定義一個辦事
    在項目中定義一個辦事,新建一個ServiceTest項目,然后在這個項目中新增一個名為MyService的類,并讓它持續(xù)自Service,完成后的代碼如下所示:

package com.jack.servicetest;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class MyService extends Service {

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}

}

今朝MyService中只用一個onBind()辦法,這個辦法是Service中獨一的一個抽象辦法,所以必須要在子類誠實現(xiàn)。既然定義了一個辦事,天然應(yīng)當在辦事中去處理一些工作,那邊那邊理工作的邏輯應(yīng)當寫在哪里?這時我們就可以重寫Service中的別的一些辦法了,如下所示:

package com.jack.servicetest;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class MyService extends Service {

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		return super.onStartCommand(intent, flags, startId);
	}
	
	

}

可以看到,這里我們又重寫了onCreate(),onDestroy()和onStartCommand(Intent intent, int flags, int startId)這三個辦法,它們是每個辦事中最常用到的三個辦法。個中onCreate辦法會在辦事創(chuàng)建的時刻調(diào)用,onStartCommand辦法會在每次辦事啟動的時刻調(diào)用。onDestroy()辦法會在辦事燒毀的時刻調(diào)用。

   平日情況下,如不雅我們欲望辦事一旦啟動就急速去履行某個動作,就可以將邏輯寫在onStartCommand辦法里。而當辦事燒毀時,我們又應(yīng)當在onDestroy()辦法中去收受接收那些不在應(yīng)用的資本。
   別的須要留意的是,沒一個辦事都須要在AndroidManifest.xml文件中進行注冊才能生效,android四大年夜組件都須要進行注冊。于是我們修改AndroidManifest.xml文件,代碼如下所示:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.jack.servicetest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="13"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.jack.servicetest.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>
        
        <service android:name="com.jack.servicetest.MyService"></service>
        
    </application>

</manifest>

如許的話,就已經(jīng)將一個辦事定義好了。


啟動和停止辦事
  定義好了辦過后,接下來就應(yīng)當推敲若何啟動以及停止這個辦事。啟動辦事和停止辦事重要借助Intent來實現(xiàn),下面我們在ServiceTest項目中測驗測驗去啟動已經(jīng)停止MyService這個辦事。
起首修改activity_main.xml中的代碼,如下所示:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <Button 
        android:id="@+id/start_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="start service"
        />

    <Button 
        android:id="@+id/stop_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="stop service"
        />
    
    
</LinearLayout>

膳綾擎的構(gòu)造重要參加了2個按鈕,用來啟動和停止辦事。
然后修改MainActivity中的代碼,如下所示:

package com.jack.servicetest;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener{

	private Button startService;
	private Button stopService;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		startService=(Button) findViewById(R.id.start_service);
		stopService=(Button) findViewById(R.id.stop_service);
		startService.setOnClickListener(this);
		stopService.setOnClickListener(this);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch(v.getId()){
		case R.id.start_service:
			Intent startIntent =new Intent(this,MyService.class);
			startService(startIntent);//啟動辦事
			break;
		case R.id.stop_service:
			Intent stopIntent =new Intent(this,MyService.class);
			stopService(stopIntent);//停止辦事
			break;
		default:
			break;
		}
	}

}

膳綾擎我們在onCreate辦法平分別獲取到start service按鈕和stop service按鈕的實例,并給它們注冊了點擊
 事宜。然后在start service按鈕的點擊事沂攀瑯綾擎,我們構(gòu)建出了一個Intent對象,并調(diào)用startService()
 辦法來啟動MyService這個辦事。在stop service按鈕的點擊事沂攀里,我們同樣構(gòu)建出了一個Intent對象,并調(diào)用
 stopService()辦法來停止MyService這個辦事。startService()和stopService()辦法都是定義在Context
 類中的,所以我們在晃蕩里可以直接調(diào)用這兩個辦法。留意,這瑯綾搶滿是由晃蕩來決定辦事何時停止的,如不雅沒有點擊stop service
 按鈕,辦事就會一向處于運行狀況。那辦事有什么辦法讓本身停下來了?只須要在MyService的任何一個地位調(diào)用shopSelf()
 辦法就能讓辦事停止下來了。



       接下來我們要推敲,若何才能證實辦事已經(jīng)成功啟動或者停止了?最簡單的辦法就是在MyService的幾個辦法中參加打印日記,如下所示:

package com.jack.servicetest;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class MyService extends Service {

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		Log.d("MyService", "onCreate()");
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		Log.d("MyService", "onDestroy()");
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		
		Log.d("MyService", "onStartCommand");
		
		return super.onStartCommand(intent, flags, startId);
		
	}
	
	

}

如今運行法度榜樣,進行測試,法度榜樣的主界面如下所示:
[img]http://img.blog.csdn.net/20141120211442358?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvajkwMzgyOTE4Mg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center



點擊一下start service按鈕,不雅察logcat打印的日記如下所示:
[img]http://img.blog.csdn.net/20141120211554945?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvajkwMzgyOTE4Mg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center



MyService中的onCreate辦法和onStartCommand辦法都履行了,解釋辦事已經(jīng)成功啟動了,并且可以在正在運行的辦事列表中找到。
在點擊下stop service,不雅察logcat日記的輸出:
[img]http://img.blog.csdn.net/20141120211833644?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvajkwMzgyOTE4Mg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center



由此證實MyService辦事確切已經(jīng)成功停止下來了。


    onCreate辦法和onStartCommand辦法的差別:onCreate辦法是在辦事第一次創(chuàng)建的時刻調(diào)用的,而onStartCommand方軌則在每次啟動辦事的時刻都邑調(diào)用,因為剛才我們是第一次點擊start service按鈕,辦事此時還未創(chuàng)建過,所以兩個辦法都邑履行,之后如不雅你在持續(xù)多點擊幾回start service按鈕,你就會發(fā)明只有onStartCommand辦法可以獲得履行了。


晃蕩和辦事進行通信
    今朝我們欲望在MyService里供給一個下載的功能,然后再晃蕩中可以決定何時開端下載,以及隨時查看下載進。實現(xiàn)這個功能的思路是創(chuàng)建一個專門的Binder對象來對下載功能進行治理,修改MyService中的代碼:如下所示:

package com.jack.servicetest;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class MyService extends Service {

	private DownloadBinder mBinder=new DownloadBinder();
	class DownloadBinder extends Binder{
		public void startDownload(){
			Log.d("MyService", "startdownload executed");
		}
		
		public int getProgress(){
			Log.d("MyService", "getProgress executed");
			return 0;
		}
		
	}
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return mBinder;
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		Log.d("MyService", "onCreate()");
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		Log.d("MyService", "onDestroy()");
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		
		Log.d("MyService", "onStartCommand");
		
		return super.onStartCommand(intent, flags, startId);
		
	}
	
	

}

這里我們新建了一個DownloadBinder類,并讓它持續(xù)自Binder,然后再它的內(nèi)部供給開端下載以及查看下載進度的辦法。當然這只是兩個模仿的辦法,并沒有實現(xiàn)真正的功能,我們在這兩個辦法平分別打印了一行日記。
   接著,在MyService中創(chuàng)建了DownloadBinder的實例,然后再onBind()辦法里返回了這個實例,如許MyService中的工作就全部完成了。
   下面我們須要在晃蕩中調(diào)用辦事里的辦法,起首須要在構(gòu)造文件中新曾兩個按鈕,修改activity_main.xml中的代碼,如下所示:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <Button 
        android:id="@+id/start_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="start service"
        />

    <Button 
        android:id="@+id/stop_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="stop service"
        />
    
    <Button 
        android:id="@+id/bind_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="bind service"
        />

    <Button 
        android:id="@+id/unbind_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="unbind service"
        />
    
    
</LinearLayout>

這兩個晃蕩用于在晃蕩中進行綁定和撤消綁定辦事,當一個晃蕩和辦事綁定了之后,就可聲調(diào)用該辦事里的Binder供給的辦法了,修改MainActivity中的代碼,如下所示:

package com.jack.servicetest;

import com.jack.servicetest.MyService.DownloadBinder;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener{

	private Button startService;
	private Button stopService;
	private Button bindService;
	private Button unbindService;
	private MyService.DownloadBinder downloadBinder;
	private ServiceConnection connection=new ServiceConnection() {
		/*
		 * 這里創(chuàng)建了一個ServiceConnection的匿名類,在這里重寫了onServiceConnected辦法和
		 * onServiceDisconnected辦法,這兩個辦法分別會在晃蕩與辦事成功綁定以及解除綁定的時刻調(diào)用。
		 * 在onServiceConnected辦法中,我們又經(jīng)由過程向下轉(zhuǎn)型獲得了DownloadBinder的實例,有了這個
		 * 實例,晃蕩和辦事之間的關(guān)系就變得異常慎密了,如今我們可以在晃蕩中根據(jù)具體的場景來調(diào)用DownloadBinder
		 * 中的任何public辦法,及實現(xiàn)了批示辦事干什么,辦事就干什么的功能,這里只做了簡單的測試,在onServiceConnected
		 * 中調(diào)用了DownloadBinder的startDownload(),getProgress()辦法。
		 * */
		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// TODO Auto-generated method stub
			downloadBinder=(MyService.DownloadBinder) service;
			downloadBinder.startDownload();
			downloadBinder.getProgress();
		}
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		startService=(Button) findViewById(R.id.start_service);
		stopService=(Button) findViewById(R.id.stop_service);
		startService.setOnClickListener(this);
		stopService.setOnClickListener(this);
		
		bindService = (Button) findViewById(R.id.bind_service);
		unbindService = (Button) findViewById(R.id.unbind_service);
		bindService.setOnClickListener(this);
		unbindService.setOnClickListener(this);
		
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch(v.getId()){
		case R.id.start_service:
			Intent startIntent =new Intent(this,MyService.class);
			startService(startIntent);//啟動辦事
			break;
		case R.id.stop_service:
			Intent stopIntent =new Intent(this,MyService.class);
			stopService(stopIntent);//停止辦事
			break;
		case R.id.bind_service:
			/*
			 *如今我們須要進行晃蕩和辦事的綁定,構(gòu)建一個Intent對象,然后調(diào)用bindService()辦法將
			 *MainActivity()和MyService進行綁定。 bindService辦法接收留個參數(shù),第一個參數(shù)就是
			 *膳綾擎創(chuàng)建出的Intent對象,第二個參數(shù)就是前面創(chuàng)建出的ServiceConnection的實例,第三個
			 *參數(shù)則是一個標記位,這里傳入BIND_AUTO_CREATE表示在晃蕩和辦事進行綁定后主動創(chuàng)建辦事。
			 *這會使得MyService中的onCreate()辦法獲得履行,但onStartCommand()辦法不會履行。
			 * */
			Intent bindIntent=new Intent(this,MyService.class);
	        bindService(bindIntent, connection, BIND_AUTO_CREATE);//綁定辦事
			break;
		case R.id.unbind_service:
			/*
			 * 如不雅我們想解除晃蕩和辦事之間的綁定,調(diào)用一下unbindService()辦法就可以了。
			 * */
			unbindService(connection);//解綁辦事
			break;
		default:
			break;
		}
	}

}

大年夜新運行下法度榜樣,界面如下所示:
[img]http://img.blog.csdn.net/20150105162929487?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvajkwMzgyOTE4Mg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center



點擊以下bind service,然后可以不雅察logcat中打印的日記如下圖所示:
[img]http://img.blog.csdn.net/20150105163058187?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvajkwMzgyOTE4Mg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center





可以看到,起首是MyService的onCreate()辦法獲得了履行,然后startDownload和getProgeress辦法獲得了履行,解釋我們確切已經(jīng)在晃蕩力成功的調(diào)用了辦事里供給的辦法了。別的須要留意的,任何一個辦事在全部應(yīng)用法度榜樣范圍內(nèi)都是通用的,即MyService不僅可以和MainActivity綁定,還可以和任何一個其他的晃蕩進行綁定,并且在綁定完成之后他們都可以獲取到雷同的DownloadBinder實例。




辦事的生命周期
        辦事也有本身的生命周期,前面我們應(yīng)用到的onCreate(),onStartCommand(),onBind()和onDestroy()等辦法
 都是在辦事的生命周期內(nèi)可能回掉落的辦法。
    一旦在項目標任何地位調(diào)用了Context的startService()辦法,響應(yīng)的辦事就會啟動起來,并回調(diào)onStartCommand()。如不雅 這個辦事之前還沒創(chuàng)建過,onCreate()辦法會先于onStartCommand()辦法履行。辦事啟動了之后一向保持運行狀況,
    直到stopService()或stopSelf()辦法被調(diào)用。留意固然每調(diào)用一次startService()辦法,onStartCommand()就會
    履行一次,但實際膳綾強個辦事都只會存在一個實例。所以不管你調(diào)用了若干次startService()辦法,只需調(diào)用一次stopService()或stopSelf()辦法,辦事就會停止下來了。
  別的,還可聲調(diào)用Context的bindService()來獲取一個辦事的持久連接,這時就會回調(diào)辦事中的onBind()辦法。類似地,如不雅這個辦事之前還沒有創(chuàng)建過,onCreate()辦法會先于onBind()辦法履行。之后,調(diào)用方可以獲取到onBind()辦法里返回的IBinder對象的實例,如許就能自由地和辦事進行通信了。只要調(diào)用方和辦事之間的連接沒有斷開,辦事就會一向保持運行狀況。
   當調(diào)用了startService()辦法后,又去調(diào)用stopService()辦法,這時辦事中的onDestroy()辦法就會履行,表示
   辦事已經(jīng)燒毀了。類似地,當調(diào)用了bindService()辦法后,又去調(diào)用unbindService()辦法,onDestroy()辦法也會履行,這
   兩種情況都很好懂得。然則須要留意,我們是完全有可能對一個辦事既調(diào)用了startService()辦法,又調(diào)用了bindService()辦法的,這種情況下該若何才能讓辦事燒毀掉落?根據(jù)android體系的機制,一個辦事只要被啟動或者綁定了之后就會一向處于運行狀況,必須要讓以上兩種前提同時不知足,辦事才能被燒毀。所以,這種情況下須要同時調(diào)用stopService()和unbindService()辦法,onDestroy()辦法才會履行。







應(yīng)用前臺辦事
       辦事幾乎都是在后臺運行的,一向以來它都是默默的做著辛苦的工作。然則辦事的體系優(yōu)先級照樣比較低的,當體系出現(xiàn)內(nèi)存不足的情況時,就有可能會收受接收掉履┞俘在后臺運行的辦事。如不雅你欲望辦事可以一向 保持運行狀況,而 不會因為體系內(nèi)存不足的原因?qū)е卤皇帐芙邮眨涂梢酝魄脩?yīng)用前臺辦事。前臺辦事和通俗辦事最大年夜的差別就在于,它會一向有一個正在運行的體系狀況欄顯示,下拉狀況欄后可以看到加倍具體的信息,異常類似于通知的效不雅。
       下面我們創(chuàng)建一個前臺辦事吧,修改MyService中的代碼,如下所示:

package com.jack.servicetest;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class MyService extends Service {

	private DownloadBinder mBinder=new DownloadBinder();
	class DownloadBinder extends Binder{
		public void startDownload(){
			Log.d("MyService", "startdownload executed");
		}
		
		public int getProgress(){
			Log.d("MyService", "getProgress executed");
			return 0;
		}
		
	}
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return mBinder;
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		@SuppressWarnings("deprecation")
		Notification notification=new Notification(R.drawable.ic_launcher,
				"Notification comes",System.currentTimeMillis());
		Intent notificationIntent=new Intent(this,MainActivity.class);
		PendingIntent pendingIntent=PendingIntent.getActivity(this, 0,notificationIntent,
				0);
		notification.setLatestEventInfo(this, "this is title", "this is content",
				pendingIntent);
		startForeground(1, notification);
		/*
		 可以看到,這里只是修改了onCreate()辦法中的代碼,信賴這部分代碼你會異常眼熟。這就是我們前面進修的
		 創(chuàng)建通知的辦法。只不過此次在構(gòu)建出Notification對象并沒有應(yīng)用NotificationManager來精曉知顯示
		 出來,而是調(diào)用了startForeground()辦法。這個辦法接收兩個參數(shù),第一個參數(shù)是通知的id,類似于notify()辦法
		 的第一個參數(shù),第二個參數(shù)則是構(gòu)建出來的Notification對象。調(diào)用startForeground()辦法后就會讓MyService變成
		 一個前臺辦事,并在體系狀況顯示出來。
		 
		 */
		Log.d("MyService", "onCreate()");
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		Log.d("MyService", "onDestroy()");
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		
		Log.d("MyService", "onStartCommand");
		
		return super.onStartCommand(intent, flags, startId);
		
	}
	
	

}

如今從新運行下法度榜樣,并點擊start service或bind service按鈕,MyService就會以前臺辦事的模式開啟了,并且在體系狀況欄會顯示一個通知擱筆,下拉狀況欄后可以看到該通知的具體內(nèi)容,如下所示:
[img]http://img.blog.csdn.net/20150105172643085?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvajkwMzgyOTE4Mg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center





應(yīng)用IntentService
   我們知道辦事中的代碼都是默認運行在主線程傍邊,如不雅直接在辦事里去處理一些耗時的邏輯,就很輕易出現(xiàn)ANR(Application Not Responding)的情況。
     所以這個時刻,就須要用到Android多線程編程的技巧了,我們應(yīng)當在辦事的每個具體的辦法里開啟一個子線程,然后再這里去處理那些耗時的邏輯。是以,一個比較標準的辦事就可以寫成如下情勢了:

package com.jack.servicetest;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class MyService extends Service {

	/*private DownloadBinder mBinder=new DownloadBinder();
	class DownloadBinder extends Binder{
		public void startDownload(){
			Log.d("MyService", "startdownload executed");
		}
		
		public int getProgress(){
			Log.d("MyService", "getProgress executed");
			return 0;
		}
		
	}*/
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		//return mBinder;
		return null;
	}

	/*@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		@SuppressWarnings("deprecation")
		Notification notification=new Notification(R.drawable.ic_launcher,
				"Notification comes",System.currentTimeMillis());
		Intent notificationIntent=new Intent(this,MainActivity.class);
		PendingIntent pendingIntent=PendingIntent.getActivity(this, 0,notificationIntent,
				0);
		notification.setLatestEventInfo(this, "this is title", "this is content",
				pendingIntent);
		startForeground(1, notification);
		
		 可以看到,這里只是修改了onCreate()辦法中的代碼,信賴這部分代碼你會異常眼熟。這就是我們前面進修的
		 創(chuàng)建通知的辦法。只不過此次在構(gòu)建出Notification對象并沒有應(yīng)用NotificationManager來精曉知顯示
		 出來,而是調(diào)用了startForeground()辦法。這個辦法接收兩個參數(shù),第一個參數(shù)是通知的id,類似于notify()辦法
		 的第一個參數(shù),第二個參數(shù)則是構(gòu)建出來的Notification對象。調(diào)用startForeground()辦法后就會讓MyService變成
		 一個前臺辦事,并在體系狀況顯示出來。
		 
		 
		Log.d("MyService", "onCreate()");
	}
*/
	/*@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		Log.d("MyService", "onDestroy()");
	}*/

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		
		Log.d("MyService", "onStartCommand");
		new Thread(new Runnable(){

			@Override
			public void run() {
				// TODO Auto-generated method stub
				//處理具體的邏輯
			}
			
		}).start();
		return super.onStartCommand(intent, flags, startId);
		
	}
	
	

}

然則,這種辦事一旦啟動之后,就會一向處于運行狀況,必須調(diào)用stopService()或者stopSelf()辦法才能讓辦事停止下來。所以,如不雅想要實現(xiàn)一個辦事履行完畢后主動停止的功能,就可以如許寫:

package com.jack.servicetest;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class MyService extends Service {

	/*private DownloadBinder mBinder=new DownloadBinder();
	class DownloadBinder extends Binder{
		public void startDownload(){
			Log.d("MyService", "startdownload executed");
		}
		
		public int getProgress(){
			Log.d("MyService", "getProgress executed");
			return 0;
		}
		
	}*/
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		//return mBinder;
		return null;
	}

	/*@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		@SuppressWarnings("deprecation")
		Notification notification=new Notification(R.drawable.ic_launcher,
				"Notification comes",System.currentTimeMillis());
		Intent notificationIntent=new Intent(this,MainActivity.class);
		PendingIntent pendingIntent=PendingIntent.getActivity(this, 0,notificationIntent,
				0);
		notification.setLatestEventInfo(this, "this is title", "this is content",
				pendingIntent);
		startForeground(1, notification);
		
		 可以看到,這里只是修改了onCreate()辦法中的代碼,信賴這部分代碼你會異常眼熟。這就是我們前面進修的
		 創(chuàng)建通知的辦法。只不過此次在構(gòu)建出Notification對象并沒有應(yīng)用NotificationManager來精曉知顯示
		 出來,而是調(diào)用了startForeground()辦法。這個辦法接收兩個參數(shù),第一個參數(shù)是通知的id,類似于notify()辦法
		 的第一個參數(shù),第二個參數(shù)則是構(gòu)建出來的Notification對象。調(diào)用startForeground()辦法后就會讓MyService變成
		 一個前臺辦事,并在體系狀況顯示出來。
		 
		 
		Log.d("MyService", "onCreate()");
	}
*/
	/*@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		Log.d("MyService", "onDestroy()");
	}*/

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		
		Log.d("MyService", "onStartCommand");
		new Thread(new Runnable(){

			@Override
			public void run() {
				// TODO Auto-generated method stub
				//處理具體的邏輯
				stopSelf();
			}
			
		}).start();
		return super.onStartCommand(intent, flags, startId);
		
	}
	
	

}

固然這種寫法并不復(fù)雜,然則總會有一些人忘記開啟線程,或者忘記調(diào)用stopSelf()辦法。為了可以簡單地創(chuàng)建一個異步的,會主動停止的辦事,android專門供給了一個IntentService類,這個類就很好的解決了前面所提到的兩種難堪,下面我們來看下它的用法。
新建一個MyIntentService類持續(xù)IntentService,代碼如下所示:

package com.jack.servicetest;

import android.app.IntentService;
import android.content.Intent;
import android.util.Log;

public class MyIntentService extends IntentService {

	/*
	 這里起首是供給了一個無參的構(gòu)造函數(shù),并且必須在其內(nèi)部調(diào)用父類的有參構(gòu)造函數(shù)。然后要在子類中去實現(xiàn)
	 onHandleIntent()這個抽象辦法,在這個辦法中可以處理一些具體的邏輯,并且不消擔(dān)心ANR的問題,因為
	 這個辦法已經(jīng)是在子線程中運行的了。這里為了證實一下,我們在onHandleIntent()辦法中打印了當前哨程的id。
	 別的根據(jù)IntentService的特點,這個辦事在運行停止后應(yīng)當是會主動停止的,所以我們又重寫了onDestroy()辦法,在
	 這里也打印l一行日記,以證實是不是停止掉落了。
	 */
	public MyIntentService() {
		super("MyIntentService");//調(diào)用父類的有參構(gòu)造函數(shù)
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void onHandleIntent(Intent arg0) {
		// TODO Auto-generated method stub

		//打印當前哨程的id
		Log.d("MyIntentService", "Thread id is "+Thread.currentThread().getId());
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		Log.d("MyIntentService", "onDestroy() executed");
	}

	
}

接下來修改activity_main.xml中的代碼,參加一個用于啟動MyIntentService這個辦事的按鈕,如下所示:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <Button 
        android:id="@+id/start_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="start service"
        />

    <Button 
        android:id="@+id/stop_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="stop service"
        />
    
    <Button 
        android:id="@+id/bind_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="bind service"
        />

    <Button 
        android:id="@+id/unbind_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="unbind service"
        />
    <Button 
        android:id="@+id/start_intent_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="start  intentservice"
        />
    
</LinearLayout>

然后修改MainActivity中的代碼,如下所示:

package com.jack.servicetest;

//import com.jack.servicetest.MyService.DownloadBinder;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener{

	private Button startService;
	private Button stopService;
	private Button bindService;
	private Button unbindService;
	private Button startIntentService;
	//private MyService.DownloadBinder downloadBinder;
	private ServiceConnection connection=new ServiceConnection() {
		/*
		 * 這里創(chuàng)建了一個ServiceConnection的匿名類,在這里重寫了onServiceConnected辦法和
		 * onServiceDisconnected辦法,這兩個辦法分別會在晃蕩與辦事成功綁定以及解除綁定的時刻調(diào)用。
		 * 在onServiceConnected辦法中,我們又經(jīng)由過程向下轉(zhuǎn)型獲得了DownloadBinder的實例,有了這個
		 * 實例,晃蕩和辦事之間的關(guān)系就變得異常慎密了,如今我們可以在晃蕩中根據(jù)具體的場景來調(diào)用DownloadBinder
		 * 中的任何public辦法,及實現(xiàn)了批示辦事干什么,辦事就干什么的功能,這里只做了簡單的測試,在onServiceConnected
		 * 中調(diào)用了DownloadBinder的startDownload(),getProgress()辦法。
		 * */
		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// TODO Auto-generated method stub
			/*downloadBinder=(MyService.DownloadBinder) service;
			downloadBinder.startDownload();
			downloadBinder.getProgress();*/
		}
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		startService=(Button) findViewById(R.id.start_service);
		stopService=(Button) findViewById(R.id.stop_service);
		startService.setOnClickListener(this);
		stopService.setOnClickListener(this);
		
		bindService = (Button) findViewById(R.id.bind_service);
		unbindService = (Button) findViewById(R.id.unbind_service);
		bindService.setOnClickListener(this);
		unbindService.setOnClickListener(this);
		
		
		startIntentService=(Button) findViewById(R.id.start_intent_service);
		startIntentService.setOnClickListener(this);
		
		
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch(v.getId()){
		case R.id.start_service:
			Intent startIntent =new Intent(this,MyService.class);
			startService(startIntent);//啟動辦事
			break;
		case R.id.stop_service:
			Intent stopIntent =new Intent(this,MyService.class);
			stopService(stopIntent);//停止辦事
			break;
		case R.id.bind_service:
			/*
			 *如今我們須要進行晃蕩和辦事的綁定,構(gòu)建一個Intent對象,然后調(diào)用bindService()辦法將
			 *MainActivity()和MyService進行綁定。 bindService辦法接收留個參數(shù),第一個參數(shù)就是
			 *膳綾擎創(chuàng)建出的Intent對象,第二個參數(shù)就是前面創(chuàng)建出的ServiceConnection的實例,第三個
			 *參數(shù)則是一個標記位,這里傳入BIND_AUTO_CREATE表示在晃蕩和辦事進行綁定后主動創(chuàng)建辦事。
			 *這會使得MyService中的onCreate()辦法獲得履行,但onStartCommand()辦法不會履行。
			 * */
			Intent bindIntent=new Intent(this,MyService.class);
	        bindService(bindIntent, connection, BIND_AUTO_CREATE);//綁定辦事
			break;
		case R.id.unbind_service:
			/*
			 * 如不雅我們想解除晃蕩和辦事之間的綁定,調(diào)用一下unbindService()辦法就可以了。
			 * */
			unbindService(connection);//解綁辦事
			break;
		case R.id.start_intent_service:
			//打印主線程的id
			Log.d("MainActivity", "Thread id is"+Thread.currentThread().getId());
			Intent intentService=new Intent(this,MyIntentService.class);
			startService(intentService);
			break;
		default:
			break;
		}
	}

}

/*
 辦事也有本身的生命周期,前面我們應(yīng)用到的onCreate(),onStartCommand(),onBind()和onDestroy()等辦法
 都是在辦事的生命周期內(nèi)可能回掉落的辦法。
    一旦在項目標任何地位調(diào)用了Context的startService()辦法,響應(yīng)的辦事就會啟動起來,并回調(diào)onStartCommand()。如不雅
    這個辦事之前還沒創(chuàng)建過,onCreate()辦法會先于onStartCommand()辦法履行。辦事啟動了之后一向保持運行狀況,
    直到stopService()或stopSelf()辦法被調(diào)用。留意固然每調(diào)用一次startService()辦法,onStartCommand()就會
    履行一次,但實際膳綾強個辦事都只會存在一個實例。所以不管你調(diào)用了若干次startService()辦法,只需調(diào)用一次stopService()
  或stopSelf()辦法,辦事就會停止下來了。
  別的,還可聲調(diào)用Context的bindService()來獲取一個辦事的持久連接,這時就會回調(diào)辦事中的onBind()辦法。類似地,
  如不雅這個辦事之前還沒有創(chuàng)建過,onCreate()辦法會先于onBind()辦法履行。之后,調(diào)用方可以獲取到onBind()辦法里
  返回的IBinder對象的實例,如許就能自由地和辦事進行通信了。只要調(diào)用方和辦事之間的連接沒有斷開,辦事就會一向保持運行狀況。
   當調(diào)用了startService()辦法后,又去調(diào)用stopService()辦法,這時辦事中的onDestroy()辦法就會履行,表示
   辦事已經(jīng)燒毀了。類似地,當調(diào)用了bindService()辦法后,又去調(diào)用unbindService()辦法,onDestroy()辦法也會履行,這
   兩種情況都很好懂得。然則須要留意,我們是完全有可能對一個辦事既調(diào)用了startService()辦法,又調(diào)用了bindService()辦法的,
   這種情況下該若何才能讓辦事燒毀掉落?根據(jù)android體系的機制,一個辦事只要被啟動或者綁定了之后就會一向處于運行狀況,必須要讓以上兩種前提同時
   不知足,辦事才能被燒毀。所以,這種情況下須要同時調(diào)用stopService()和unbindService()辦法,onDestroy()辦法才會履行。
 */






     可以看到,我們在start intentservice按鈕的點擊事沂攀瑯綾擎去啟動MyIntentService這個辦事,并在這里打印了一下主線程的id,其實IntentService的用法和通俗的辦事沒什么兩樣。
在AndroidManifest.xml里注冊,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.jack.servicetest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="13"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.jack.servicetest.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>
        
        <service android:name="com.jack.servicetest.MyService"></service>
        <service android:name="com.jack.servicetest.MyIntentService"></service>
    </application>

</manifest>

從新運行法度榜樣,界面如下所示:
[img]http://img.blog.csdn.net/20150105182349250?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvajkwMzgyOTE4Mg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center



點擊start intentservice按鈕后,不雅察LogCat中打印的日記,如下所示:
[img]http://img.blog.csdn.net/20150105182540578?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvajkwMzgyOTE4Mg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center





可以看到MyIntentService和MainActivity地點的線程id不一樣,并且onDestory()辦法也獲得了履行,解釋MyIntentService在運行完畢后確切主動停止了。集開啟線程和主動停止于一身。






辦事的最佳實踐---------后臺履行的準時義務(wù)
     Android中實現(xiàn)準時義務(wù)一般有兩種方法,一種是應(yīng)用java api里供給的Timer類,一種是應(yīng)用android的Alarm機制。
       這兩種方法在多半情況下都能實現(xiàn)類似的效不雅,然則Timer有一個明顯的短板,它并不太實用于那些須要經(jīng)久在后臺運行的準時義務(wù)。我們都知道,為了能讓電池加倍耐用,每種手機都邑有本身的休眠策略,andorid手機就會在長時光不操作的情況下主動讓cpu進入的到睡眠狀況,這就有可能導(dǎo)致Timer中的準時義務(wù)無法正常運行。而Alarm機制不存在這種情況,它具有喚醒cpu的功能,即可以包管每次須要履行準時義務(wù)的時刻cpu都能正常工作。須要留意,這里的喚醒cpu和喚醒屏幕完全不是同一個概念,不要弄混淆了。
        我們來看看Alarm機制的用法吧,重要須要借助AlarmManager類來實現(xiàn)。這個類和NotificationManager有點類似,都是經(jīng)由過程調(diào)用Context的getSystemService()辦法來獲取實例的,只是這里須要傳入的參數(shù)是Context.ALARM_SERVICE.
   是以,獲取一個AlarmManager的實例就可以寫成:
   AlarmManager manager=(AlarmManager)getSystemService(Context.ALARM_SERVICE);
   接下來調(diào)用AarmManager的set()辦法就可以設(shè)置一個準時義務(wù)了,比如說想要設(shè)定一個義務(wù)在10秒后履行,就可以寫成:
   long triggerAtTime=SystemClock.elapsedRealtime()+10*1000;
   manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,triggerAtTime,pendingIntent);
   第一個參數(shù)是一個整形參數(shù),用于指定AlarmManager的工作類型,有四種值可選,分別是ELAPSED_REALTIME,ELAPSED_REALTIME_WAKEUP,
   RTC 和   RTC_WAKEUP。個中ELAPSED_REALTIME表示讓準時義務(wù)的觸發(fā)大年夜體系開機開端算起,但不會喚醒cpu。
   ELAPSED_REALTIME_WAKEUP同樣表示讓準時義務(wù)的觸發(fā)時光大年夜體系開機開端算起,但會喚醒cpu。
   RTC表示讓準時義務(wù)的觸發(fā)時光大年夜1970年1月1日0點開端算起,但不會喚醒cpu。
  RTC_WAKEUP同樣表示讓準時義務(wù)的觸發(fā)時光大年夜1970年1月1日0點開端算起,但會喚醒cpu。應(yīng)用SystemClock.elapsedRealtime()辦法
   可以獲取到體系開機至今所歷經(jīng)的毫秒數(shù),應(yīng)用System.currentTimeMillis()辦法可以獲取到1970年1月1日0點
   至今所經(jīng)歷時光的毫秒數(shù)。
     第二個參數(shù)就是準時義務(wù)觸發(fā)的時光,以毫秒為單位。如不雅第一個參數(shù)應(yīng)用的是ELAPSED_REALTIME或ELAPSED_REALTIME_WAKEUP則這里傳入開機至今的時光在加上延遲履行的時光。如不雅第一個參數(shù)應(yīng)用的是RTC或RTC_WAKEUP,則這里傳入1970年1月1日0點至今的時光再加上延遲履行的時光。
  第三個參數(shù)是一個PendingIntent,對于它應(yīng)當不會陌生了 吧。這里我們一般會調(diào)用getBroadcast()辦法來
  獲取一個可以或許履行廣播的PendingIntent。如許當準時義務(wù)被觸發(fā)的時刻,廣播接收器的onReceive()辦法就可以獲得履行。
  懂得了 set()辦法的每個參數(shù)之后,你應(yīng)當能想到,設(shè)定一個義務(wù)在10秒后履行還可以寫成:
  long triggerAtTime=System.curentTimeMillis()+10*1000;
  manager.set(AlarmManager.RTC_WAKEUP,triggerAtTime,pendingIntent);
  如今已經(jīng)控制了Alarm機制的根本用法,下面我們就來創(chuàng)建一個可以經(jīng)久在后臺履行準時義務(wù)的辦事。創(chuàng)建一個ServiceBestPractice項目,
  然后新增一個LongRunningService類,代碼如下所示:
   
package com.jcak.servicebestpractice;

import java.util.Date;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.Log;

public class LongRunningService extends Service {

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		new Thread(new Runnable(){

			@Override
			public void run() {
				// TODO Auto-generated method stub
				Log.d("LongRunningService","executed at "+new Date().toString());
			}
			
		}).start();
		AlarmManager manager=(AlarmManager) getSystemService(ALARM_SERVICE);
		int anHour=10*1000;
		long triggerAtTime=SystemClock.elapsedRealtime()+anHour;
		Intent i=new Intent(this,AlarmReceiver.class);
		PendingIntent pi=PendingIntent.getBroadcast(this, 0, i, 0);
		manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 
				triggerAtTime, pi);
		
		return super.onStartCommand(intent, flags, startId);
	}

}

在onStartCommand()辦法中開啟了一個子線程,然后在子線程里就可以履行具體的邏輯操作了,這里簡單的,只是打印了當前的時光。
    創(chuàng)建線程之后的代碼就是膳綾擎講解的Alarm機制的用法,先是獲取到了AlarmManager的實例,然后定義義務(wù)的觸發(fā)時光為10秒,在應(yīng)用PendingIntent指定處理準時義務(wù)的廣播接收器為AlarmReceiver,最后調(diào)用set()辦法完成設(shè)定。顯然,AlarmReceiver不存在,我們就創(chuàng)建一個,代碼如下所示:

package com.jcak.servicebestpractice;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class AlarmReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub

		Intent i=new Intent(context,LongRunningService.class);
		context.startService(i);
	}

}

      onReceiver()辦法里的代碼異常簡單,就是構(gòu)建出了一個Intent對象,然后去啟動LongRunningService這個辦事
。這就已經(jīng)將一個經(jīng)久辦事在后臺準時運行的辦事完成了。因為一旦啟動了LongRunningService,就會在onStartCommand()辦法里設(shè)定一個準時義務(wù),如許10秒后AlarmReceiver的onReceive()辦法就將獲得履行了,然后我們在這里再次啟動LongRunningService,如許就形成了一個永遠的輪回,包管LongRunningService可以每隔10秒就會啟動一次,這個經(jīng)久在后臺運行的辦事就完成了。
     接下來,我們須要在打開法度榜樣的時刻啟動一次LongRunningService,之后LongRunningService就可以一向運行了。修改MainActivity中的代碼,如下所示:

package com.jcak.servicebestpractice;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		Intent intent=new Intent(this,LongRunningService.class);
		startService(intent);
		
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}

最后要注冊辦事和廣播,代碼如下所示:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.jcak.servicebestpractice"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="13"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.jcak.servicebestpractice.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>
        
        
        <service android:name="com.jcak.servicebestpractice.LongRunningService"></service>
        <receiver android:name="com.jcak.servicebestpractice.AlarmReceiver"></receiver>
    </application>

</manifest>

如今運行一下法度榜樣,然后不雅察LogCat中打印的日記,如圖所示:
[img]http://img.blog.csdn.net/20150105220927069?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvajkwMzgyOTE4Mg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center



可以看到LongRunningService每隔10秒打印一條日記。
別的須要留意的是,大年夜android4.4版開端,Alarm義務(wù)的觸發(fā)時光將會變得不精確,有可能會延遲一段時光后義務(wù)才能獲得履行。這并不是bug,而是體系在耗電方面進行的優(yōu)化。體系會主動檢測今朝有若干Alarm義務(wù)存在,然后將觸發(fā)時光將近的幾個義務(wù)存放在一路履行,這就可以大年夜幅度削減cpu被喚醒的次數(shù),大年夜而有效延長電池的應(yīng)用時光。
   當然,如不雅請求Alarm義務(wù)的履行時光必須精確無誤,android仍然供給l解決籌劃。應(yīng)用AlarmManager的setExact()辦法來替代set()辦法,就可以包管義務(wù)準時履行了。




http://blog.csdn.net/j903829182/article/details/41320241



相關(guān)案例查看更多