首先在实例之前先看下service的概念用途以及生命周期:

Service概念及用途:

Android中的服务,它与Activity不同,它是不能与用户交互的,不能自己启动的,运行在后台的程序,如果我们退出应用时,Service进程并没有结束,它仍然在后台运行,那 我们什么时候会用到Service呢?比如我们播放音乐的时候,有可能想边听音乐边干些其他事情,当我们退出播放音乐的应用,如果不用Service,我 们就听不到歌了,所以这时候就得用到Service了,又比如当我们一个应用的数据是通过网络获取的,不同时间(一段时间)的数据是不同的这时候我们可以 用Service在后台定时更新,而不用每打开应用的时候在去获取。

注意:

1.Service不能自己运行,需要通过某一个Activity或者其他Context对象来调用, Context.startService()和Context.bindService()。

通过startService:

Service会经历 onCreate -> onStart, stopService的时候直接onDestroy,如果是调用者自己直接退出而没有调用stopService的话,Service会一直

在后台运行。下次调用者再起来可以stopService。

  通过bindService:
      Service只会运行onCreate,这个时候调用者和Service绑定在一起,调用者退出了,Srevice就会调用onUnbind->onDestroyed所谓绑定在一起就共存亡了。
 Service的onCreate的方法只会被调用一次,就是你无论多少次的startService又bindService,Service只被创建一次。如果先是bind了,那么start的时候
 就直接运行Service的onStart方法,如果先是start,那么bind的时候就直接运行onBind方法。如果你先bind上了,就stop不掉了,对啊,就是stopService不好了,
只能先UnbindService, 再StopService,所以是先start还是先bind行为是有区别的.
2.Service是跑在主线程中,如果在service的onCreate或onStart方法中有耗时操作,需要放到单独的线程中,否则会影响 到UI操作或者阻塞主线程中的其他事情或者抛出ANR异常.
Service生命周期:
Android Service的生命周期并不像Activity那么复杂,它只继承了onCreate(),onStart(),onDestroy()三个方法,当我们第一次启动Service时,先后调用了
onCreate(),onStart()这两个方法,当停止Service时,则执行onDestroy()方法,这里需要注意的是,如果Service已经启动了,当我们再次启动Service时,
不会在执行onCreate()方法,而是直接执行onStart()方法

Service与Activity通信:

Service后端的数据最终还是要呈现在前端Activity之上的,因为启动Service时,系统会重新开启一个新的进程,这就涉及到不同进程间通信的问题了(AIDL),

当我们想获取启动的Service实例时,我们可以用到bindService和onBindService方法,它们分别执行了Service中IBinder()和onUnbind()方法。

通常每个应用程序都在它自己的进程内运行,但有时需要在进程间传递对象,你可以通过应用程序UI的方式写个运行在一个不同的进程中的service。

在android平台中,一个进程通常不能访问其他进程中的内存区域。所以,他们需要把对象拆分成操作系统能理解的简单形式,以便伪装成对象跨越边界访问。

编写这种伪装代码相当的枯燥乏味,好在android为我们提供了AIDL工具可以来做这件事。

AIDL与Service

AIDL是一个IDL语言,它可以生成一段代码,可以使在一个android设备上运行的两个进程使用内部通信进程进行交互。如果你需要在一个进程中

(例如:在**一个Activity中)访问另一个进程中(例如:一个Service)某个对象的方法,你就可以使用AIDL来生成这样的代码来伪装传递各种参数。

要使用AIDL,Service需要以aidl文件的方式提供服务接口,AIDL工具将生成一个相应的java接口,并且在生成的服务接口中包含一个功能调用的stub服务桩类。

Service的实现类需要去继承这个stub服务桩类。Service的onBind方法会返回实现类的对象,之后你就可以使用它了

以下是一个Service的实例:

xml文件:
                      <?            xml version="1.0" encoding="utf-8"            ?>             
< LinearLayout xmlns:android ="http://schemas.android.com/apk/res/android"
android:orientation
="vertical"
android:layout_width
="fill_parent"
android:layout_height
="fill_parent"
>
< TextView
android:id ="@+id/text"
android:layout_width
="fill_parent"
android:layout_height
="wrap_content"
android:text
="@string/hello"
/>
< Button
android:id ="@+id/startservice"
android:layout_width
="fill_parent"
android:layout_height
="wrap_content"
android:text
="startService"
/>
< Button
android:id ="@+id/stopservice"
android:layout_width
="fill_parent"
android:layout_height
="wrap_content"
android:text
="stopService"
/>
< Button
android:id ="@+id/bindservice"
android:layout_width
="fill_parent"
android:layout_height
="wrap_content"
android:text
="bindService"
/>
< Button
android:id ="@+id/unbindservice"
android:layout_width
="fill_parent"
android:layout_height
="wrap_content"
android:text
="unbindService"
/>
</ LinearLayout >

Service代码:

                      import             android.app.Service; 
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.text.format.Time;
import android.util.Log;
public class OutService extends Service {
// 定义个一个Tag标签
private static final String TAG = "Out Service " ;
// 这里定义吧一个Binder类,用在onBind()有方法里,这样Activity那边可以获取到
private MyBinder mBinder = new MyBinder(); private OutServiceAIDL.Stub aBinder = new OutServiceAIDL.Stub(){    @Override    public String getSystemTime() throws RemoteException { Time t = new Time(); t.setToNow(); return t.toString()+" ------>aidl"; } };
@Override
public IBinder onBind(Intent intent) {
Log.e(TAG,
" start IBinder~~~ " );
//
return mBinder; //未使用aidl return aBinder; //使用aidl
}
@Override
public void onCreate() {
Log.e(TAG,
" start onCreate~~~ " );
super .onCreate();
}

@Override
public void onStart(Intent intent, int startId) {
Log.e(TAG,
" start onStart~~~ " );
super .onStart(intent, startId);
}

@Override
public void onDestroy() {
Log.e(TAG,
" start onDestroy~~~ " );
super .onDestroy();
}


@Override
public boolean onUnbind(Intent intent) {
Log.e(TAG,
" start onUnbind~~~ " );
return super .onUnbind(intent);
}

// 这里我写了一个获取当前时间的函数,不过没有格式化就先这么着吧
public String getSystemTime(){

Time t
= new Time();
t.setToNow();
return t.toString();
}

public class MyBinder extends Binder{
MyService getService()
{
return MyService. this ;
}
}
}

Activity代码:

                      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.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class ServiceDemo extends Activity implements OnClickListener{

private MyService mMyService;
private OutServiceAIDL aService;
private TextView mTextView;
private Button startServiceButton;
private Button stopServiceButton;
private Button bindServiceButton;
private Button unbindServiceButton;
private Context mContext;

// 这里需要用到ServiceConnection在Context.bindService和context.unBindService()里用到
private ServiceConnection mServiceConnection = new ServiceConnection() {
// 当我bindService时,让TextView显示MyService里getSystemTime()方法的返回值
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
//mMyService = ((MyService.MyBinder)service).getService();
//mTextView.setText(
" I am frome Service : " + mMyService.getSystemTime());

aService
= OutServiceAIDL.Stub.asInterface(service);
try {
mTextView.setText(
" I am frome Service aidl: " + aService.getSystemTime());
}
catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub

}
};
public void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout.main);
setupViews();
}

public void setupViews(){

mContext
= ServiceDemo. this ;
mTextView
= (TextView)findViewById(R.id.text);



startServiceButton
= (Button)findViewById(R.id.startservice);
stopServiceButton
= (Button)findViewById(R.id.stopservice);
bindServiceButton
= (Button)findViewById(R.id.bindservice);
unbindServiceButton
= (Button)findViewById(R.id.unbindservice);

startServiceButton.setOnClickListener(
this );
stopServiceButton.setOnClickListener(
this );
bindServiceButton.setOnClickListener(
this );
unbindServiceButton.setOnClickListener(
this );
}

public void onClick(View v) {
// TODO Auto-generated method stub
if (v == startServiceButton){
Intent i
= new Intent();
i.setClass(ServiceDemo.
this , MyService. class );
mContext.startService(i);
}
else if (v == stopServiceButton){
Intent i
= new Intent();
i.setClass(ServiceDemo.
this , MyService. class );
mContext.stopService(i);
}
else if (v == bindServiceButton){
Intent i
= new Intent();
i.setClass(ServiceDemo.
this , MyService. class );
mContext.bindService(i, mServiceConnection, BIND_AUTO_CREATE);
}
else {
mContext.unbindService(mServiceConnection);
}
}
}
aidl文件:
                  interface           OutServiceAIDL {
String getSystemTime();
}

更多相关文章

  1. 一款霸榜 GitHub 的开源 Linux 资源监视器!
  2. Android(安卓)8.0以上系统应用如何保活
  3. Android(安卓)MVP 模式 项目初体验(一)
  4. Android之Handler、Looper、MessageQueue源码分析.md
  5. 学习Android闹钟源代码(三)-AlarmClock类分析(part1)
  6. adb通过wifi连接方法
  7. Android抓包方法(一)之Fiddler代理
  8. Android(安卓)消息机制(Handler Looper Message )理解
  9. 关于android:sharedUserId="android.uid.system"这个系统级权限

随机推荐

  1. 开源终端Android Terminal Emulator
  2. 系出名门Android(2) - 布局(Layout)和菜
  3. Freeline 一款 Android平台上的秒级编译
  4. Android下使用Socket连接网络电脑
  5. LinearLayout 内部控件居中
  6. android系统权限关机重启
  7. 【Android】Android(安卓)签名相关问题
  8. CoordinatorLayout使用自定义Behavior实
  9. NestedScrollView中webview被点击,NestedS
  10. 占位的实现和间接实现从快捷建中启动一个