Android 中有幾個重要的組件,其中之一就是Service,這是沒有UI的組件,可以做為背景服務,當然可以使用Intent來啟動。同時也可以綁定到宿主對象(調用者,常是Activity)來使用,
注意:
一,Android中的Service與調用者在同一線程,所以要是耗時的操作要在Service中新開線程。
二,Android的Service中,主要是實現其onCreate,onStart, onDestroy,onBind,onUnBind幾個函數,來實現我們所需要的功能。
簡單的調用:
簡單的調可以在調用者對象中使用Context.startService來調用,以Intent為參數,當然,Intent搜尋,匹配目標的方式與以前在《Intent使用》中方式一樣。
下面來看一段常式:
一,聲明Service子類。
public class TestService extends Service {
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Toast.makeText(this, "Service Created!", Toast.LENGTH_SHORT).show();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Toast.makeText(this, "Service Destroyed!", Toast.LENGTH_LONG).show();
}
@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
Toast.makeText(this, "Service Started...", Toast.LENGTH_LONG).show();
}
@Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
super.onUnbind(intent);
Toast.makeText(this, "Service unBind!", Toast.LENGTH_LONG).show();
return true;
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(this, "Service Bound!", Toast.LENGTH_LONG).show();
return null;
}
}
在Manifest.xml中配置此Service.
....
<service android:label="@string/hello" android:name="TestService">
<intent-filter>
<action android:name="start_service"></action>
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
</service>
....
建立調用者類:
mport android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
public class HelloActivity extends Activity {
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
super.onCreateOptionsMenu(menu);
menu.add(0, Menu.FIRST+1, 1, R.string.menu_open);
menu.add(0, Menu.FIRST+2, 2, "StartService");
menu.add(0, Menu.FIRST+3, 3, "StopService");
menu.add(0, Menu.FIRST+4, 4, R.string.menu_close);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
super.onOptionsItemSelected(item);
switch(item.getItemId())
{
case Menu.FIRST + 1:
{
this.setTitle("Switch Activity");
Intent i = new Intent();
i.setAction("test_action");
if (Tools.isIntentAvailable(this,i))
this.startActivity(i);
else
this.setTitle("the Intent is unavailable!!!");
break;
}
case Menu.FIRST + 2:
{
this.setTitle("Start Service");
//Intent i = new Intent(this, TestService.class);
Intent i = new Intent();
i.setAction("start_service");
this.startService(i);
break;
}
case Menu.FIRST + 3:
{
this.setTitle("Stop Service");
Intent i = new Intent(this, TestService.class);
this.stopService(i);
break;
}
case Menu.FIRST + 4:
{
this.setTitle("Close Text!");
break;
}
}
return true;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.main);
}
}
注意:在操作Service時,我使用了兩種Intent方式,一種是顯示的直接寫TestService.class,此方法只能操作當前應用程式中的Service,一種是隱式的,可以根據Manifest.xml操作不同進程中的Service.
綁定的使用方法:
一,聲明一個Service介面,這個提供功能給調用者。
package test.pHello;
public interface ITestService {
public void showName();
}
二,定義Service,實現了onBind 函數,並返回一個ITestService的實現對象。
package test.pHello;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.widget.Toast;
public class TestService extends Service {
public class Test extends Binder implements ITestService
{
private Context mContext = null;
public void showName() {
Toast.makeText(mContext, "MyName is TestService", Toast.LENGTH_LONG).show();
}
public void setContext(Context c){mContext = c;};
}
Test mTestImplement = new Test();
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Toast.makeText(this, "Service Created!", Toast.LENGTH_SHORT).show();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Toast.makeText(this, "Service Destroyed!", Toast.LENGTH_LONG).show();
}
@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
Toast.makeText(this, "Service Started...", Toast.LENGTH_LONG).show();
}
@Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
super.onUnbind(intent);
Toast.makeText(this, "Service unBind!", Toast.LENGTH_LONG).show();
return true;
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
mTestImplement.setContext(this);
Toast.makeText(this, "Service Bound!", Toast.LENGTH_LONG).show();
return mTestImplement;
}
}
三,在調用者方面,進行綁定,取得ITestService介面引用。
package test.pHello;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
public class HelloActivity extends Activity {
ITestService mService = null;
ServiceConnection sconnection = new ServiceConnection()
{
public void onServiceConnected(ComponentName name, IBinder service)
{
mService = (ITestService)service;
if (mService != null)
{
mService.showName();
}
}
public void onServiceDisconnected(ComponentName name)
{
}
};
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
super.onCreateOptionsMenu(menu);
menu.add(0, Menu.FIRST+1, 1, "OpenActivity");
menu.add(0, Menu.FIRST+2, 2, "StartService");
menu.add(0, Menu.FIRST+3, 3, "StopService");
menu.add(0, Menu.FIRST+4, 4, "BindService");
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
super.onOptionsItemSelected(item);
switch(item.getItemId())
{
case Menu.FIRST + 1:
{
this.setTitle("Switch Activity");
Intent i = new Intent();
i.setAction("test_action");
if (Tools.isIntentAvailable(this,i))
this.startActivity(i);
else
this.setTitle("the Intent is unavailable!!!");
break;
}
case Menu.FIRST + 2:
{
this.setTitle("Start Service");
//Intent i = new Intent(this, TestService.class);
Intent i = new Intent();
i.setAction("start_service");
this.startService(i);
break;
}
case Menu.FIRST + 3:
{
this.setTitle("Stop Service");
Intent i = new Intent(this, TestService.class);
this.stopService(i);
break;
}
case Menu.FIRST + 4:
{
this.setTitle("Bind Service!");
Intent i = new Intent(this, TestService.class);
this.bindService(i, this.sconnection, Context.BIND_AUTO_CREATE);
break;
}
}
return true;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.main);
}
}
編譯執行,你會發現,是先執行onCreate,然後再執行onBind,在調用者的Context.bindService返回時,ServiceConnection的OnConnected並沒有馬上被執行。
遠程綁定:
上述綁定是在調用者與Service在同一個應用程式中的情況,如果分處在不同的程式中,那麼,調用方式又是一另一種情況。我們來看一下。