Android 学习心得(9)——Service(上)

时间:2022-12-12 16:26:45

 

  分类:Android主要分为本地service和远程service

  service生命周期图

 Android 学习心得(9)——Service(上)

  service方法详解

注:所有释义都在代码中请自己在展开

Android 学习心得(9)——Service(上)Android 学习心得(9)——Service(上)
  1 import android.app.Service;
  2 import android.content.Intent;
  3 import android.content.res.Configuration;
  4 import android.os.IBinder;
  5 
  6 public class newSer extends Service {
  7 
  8     /**
  9      * 因为Service是没有用户界面的所以onPause() onResume() onStop是不需要的,service总是在后台运行
 10      * 需要注意的是这些方法都可以不用调用父类的方法就可以使用了
 11      * 关于停止Service,如果service是非绑定的,最终当任务完成时,为了节省系统资源,一定要停止service,
 12      * 可以通过stopSelf()来停止,stopSelf可以放在onStart/onStartCommand中代码结束的时候,也可以在其他组件中通过stopService()来停止,
 13      * 绑定的service可以通过onUnBind()来停止service。
 14      */
 15     /**
 16      * Context.startService方式的生命周期: 
 17     启动时,startService –> onCreate() –> onStart() 
 18     停止时,stopService –> onDestroy()
 19     
 20     Context.bindService方式的生命周期: 
 21     绑定时,bindService  -> onCreate() –> onBind() 
 22     运行时,onReBind() 
 23     解绑定时,unbindService –>onUnbind() –> onDestory()
 24      */
 25     
 26     
 27     @Override
 28     public IBinder onBind(Intent arg0) {
 29         /**
 30          * 如果一个客户端需要持久的连接到一个服务,那么他可以调用Context.bindService方法。
 31          * 如果这个服务没有运行方法将通过调用onCreate方法去创建这个服务但并不调用onStart方法来启动它。
 32          * 相反,onBind方法将被客户端的Intent调用,并且它返回一个IBind对象以便客户端稍后可以调用这个服务。
 33          * 通常称之为“绑定服务”
 34          */
 35         return null;
 36     }
 37 
 38     @Override
 39     public void onConfigurationChanged(Configuration newConfig) {
 40         /**
 41          * 官方原版描述是这样的 
 42          * Called by the system when the device configuration changes while your component is running. Note that, unlike activities, other components are never restarted when a configuration changes: they must always deal with the results of the change, such as by re-retrieving resources.
 43     At the time that this function has been called, your Resources object will have been updated to return resource values matching the new configuration.
 44          * 大致意思是当系统状态发生变化的时候调用
 45          * 我的理解是在服务在崩溃的时候保存资源的时候调用
 46          * 跟Activity中的方法一样
 47          */
 48         super.onConfigurationChanged(newConfig);
 49     }
 50 
 51     @Override
 52     public void onCreate() {
 53         /**
 54          * 通过从客户端调用Context.startService(Intent)方法我们可以启动一个服务。
 55          * 如果这个服务还没有运行,Android将启动它并且在onCreate方法之后调用它的onStart/onStartCommand方法。
 56          * 但是请注意在这个服务正在运行的时候,它的onCreate方法是不被调用的,只会去调用它的onStart/onStartCommand方法。
 57          * 这个方法主要负责Service的初始化工作,例如实例化对象
 58          */
 59         super.onCreate();
 60     }
 61 
 62     @Override
 63     public void onDestroy() {
 64         /**
 65          * 与Activity一样,当一个服务被结束是onDestroy方法将会被调用。
 66          * 当没有客户端启动或绑定到一个服务时Android将终结这个服务。
 67          * 与很多Activity时的情况一样,当内存很低的时候Android也可能会终结一个服务。
 68          * 如果这种情况发生,Android也可能在内存够用的时候尝试启动被终止的服务,
 69          * 所以你的服务必须为重启持久保存信息,并且最好在onStart/onStartCommand方法内来做
 70          */
 71         super.onDestroy();
 72     }
 73 
 74     @Override
 75     public void onRebind(Intent intent) {
 76         /**
 77          * 当服务已经被bindService调用之后,下次则不会去调用onBind,而会调用这个方法
 78          */
 79         
 80         super.onRebind(intent);
 81     }
 82 
 83     @Override
 84     public void onStart(Intent intent, int startId) {
 85         /**
 86          *Context.startService方式启动服务的时候,
 87          * 服务所提供的主要任务是安排在这里进行的,
 88          */
 89         super.onStart(intent, startId);
 90     }
 91 
 92     @Override
 93     public int onStartCommand(Intent intent, int flags, int startId) {
 94         /**
 95          * 在2.0版本之后onStart方法被替换为onStartCommand,
 96          * 当两个方法同时存在的时候不会产生冲突,两个方法都会被调用到
 97          * 调用顺序为onStartCommand -> onStart
 98          * 这个方法会返回一个整型值分别为:
 99          *1):START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,
100          *          但不保留递送的intent对象。随后系统会尝试重新创建service,
101          *       由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。
102          *       如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
103          *2):START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务
104          *3):START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
105          *4):START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
106 
107  
108          */
109         return super.onStartCommand(intent, flags, startId);
110     }
111 
112 
113     @Override
114     public boolean onUnbind(Intent intent) {
115         /**
116          * 当你不需要绑定的时候就执行 unbindService() 方法,
117          * 执行这个方法只会触发 Service 的 onUnbind() 
118          * 而不会把这个 Service 销毁。
119          * 多个组件可以绑定一个service.
120          */
121         return super.onUnbind(intent);
122     }
123     
124 }
service方法详解

  service调用

Android 学习心得(9)——Service(上)Android 学习心得(9)——Service(上)
  1 package com.example.useLocalService;
  2 
  3 import com.example.uselocalservice.R;
  4 import android.annotation.SuppressLint;
  5 import android.app.Activity;
  6 import android.app.Service;
  7 import android.content.ComponentName;
  8 import android.content.Intent;
  9 import android.content.ServiceConnection;
 10 import android.os.Bundle;
 11 import android.os.Handler;
 12 import android.os.IBinder;
 13 import android.os.Message;
 14 import android.util.Log;
 15 import android.view.View;
 16 import android.view.View.OnClickListener;
 17 import android.widget.Button;
 18 import android.widget.EditText;
 19 import android.widget.TextView;
 20 
 21 @SuppressLint("HandlerLeak")
 22 public class newAct extends Activity implements OnClickListener {
 23     private final static String TAG = "myService";
 24     private newSer myNewSer;
 25     /**
 26      * Context.startService方式的生命周期: 
 27     启动时,startService –> onCreate() –> onStart() 
 28     停止时,stopService –> onDestroy()
 29     
 30     Context.bindService方式的生命周期: 
 31     绑定时,bindService  -> onCreate() –> onBind() 
 32     解绑定时,unbindService –>onUnbind() –> onDestory()
 33      */
 34     
 35     private Button bt_start;
 36     private Button bt_stop;
 37     private Button bt_bind;
 38     private Button bt_rebind;
 39     private Button bt_unbind;
 40     private Button bt_find;
 41     private TextView find;
 42     private EditText ed_id;
 43     private ServiceConnection conn = new ServiceConnection() {
 44         
 45         @Override
 46         public void onServiceDisconnected(ComponentName arg0) {
 47             /**
 48              * 断开连接时候调用
 49              */
 50             Log.i(TAG, "断开连接"); 
 51             myNewSer = null;
 52         }
 53         
 54         @Override
 55         public void onServiceConnected(ComponentName arg0, IBinder arg1) {
 56             /**
 57              * 建立连接提供给Activity和Service进行交互的方法,连接成功调用
 58              */
 59             Log.i(TAG, "建立连接"); 
 60             myNewSer = ((newSer.MyBinder)  arg1).getService();
 61         }
 62     };
 63     
 64     private Handler myhandler = new Handler(){
 65 
 66         @Override
 67         public void handleMessage(Message msg) {
 68             //更新UI
 69             String myname = msg.getData().getString("name");
 70             find.setText(myname);
 71             
 72             super.handleMessage(msg);
 73             
 74         }
 75         
 76     };
 77     private String name;
 78     @Override
 79     protected void onCreate(Bundle savedInstanceState) {
 80         super.onCreate(savedInstanceState);
 81         setContentView(R.layout.new_layout);
 82         
 83         //实例化对象
 84         bt_start = (Button) findViewById(R.id.bt_start);
 85         bt_stop = (Button) findViewById(R.id.bt_stop);
 86         bt_bind = (Button) findViewById(R.id.bt_bind);
 87         bt_rebind = (Button) findViewById(R.id.bt_rebind);
 88         bt_unbind = (Button) findViewById(R.id.bt_unbind);
 89         bt_find = (Button) findViewById(R.id.bt_find);
 90         find = (TextView) findViewById(R.id.find);
 91         ed_id = (EditText) findViewById(R.id.ed_id);
 92         
 93         //设置监听器
 94         bt_start.setOnClickListener(this);
 95         bt_stop.setOnClickListener(this);
 96         bt_bind.setOnClickListener(this);
 97         bt_rebind.setOnClickListener(this);
 98         bt_unbind.setOnClickListener(this);
 99         bt_find.setOnClickListener(this);
100         
101     }
102     @Override
103     public void onClick(View v) {
104         Intent mIntent = new Intent();
105         mIntent.setClass(getApplicationContext(), newSer.class);
106         switch (v.getId()) {
107         /**
108          * 前两个是start方式启动服务
109          */
110         case R.id.bt_start:
111                 startService(mIntent);
112             break;
113         case R.id.bt_stop:
114                 stopService(mIntent);
115             break;
116         case R.id.bt_bind:
117                 bindService(mIntent, conn, Service.BIND_AUTO_CREATE);//常量的含义是自动运行onCeate方法
118             break;
119         case R.id.bt_rebind:
120                 bindService(mIntent, conn, Service.BIND_AUTO_CREATE);//常量的含义是自动运行onCeate方法
121             break;
122         case R.id.bt_unbind:
123                 unbindService(conn);
124                 
125             break;
126         case R.id.bt_find:
127             int mid = Integer.parseInt(ed_id.getText().toString());
128             name = myNewSer.findNameById(mid);
129             
130             //更新UI
131             new Thread(){
132                 public void run(){
133                     Message msg = new Message();
134                     Bundle mBundle= new Bundle();
135                     mBundle.putString("name", name);
136                     msg.setData(mBundle);
137                     newAct.this.myhandler.sendMessage(msg);
138                 }
139             }.start();
140         break;
141         }
142         
143     }
144 
145     
146     
147     
148 }
service调用源码

  这是界面

Android 学习心得(9)——Service(上)Android 学习心得(9)——Service(上)
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical" ><Button
 6         android:id="@+id/bt_start"
 7         android:layout_width="wrap_content"
 8         android:layout_height="wrap_content"
 9         android:text="@string/bt_start" />
10 
11     <Button
12         android:id="@+id/bt_stop"
13         android:layout_width="wrap_content"
14         android:layout_height="wrap_content"
15         android:text="@string/bt_stop" />
16 
17     <Button
18         android:id="@+id/bt_bind"
19         android:layout_width="wrap_content"
20         android:layout_height="wrap_content"
21         android:text="@string/bt_bind" />
22 
23     <Button
24         android:id="@+id/bt_rebind"
25         android:layout_width="wrap_content"
26         android:layout_height="wrap_content"
27         android:text="@string/bt_rebind" />
28 
29     <Button
30         android:id="@+id/bt_unbind"
31         android:layout_width="wrap_content"
32         android:layout_height="wrap_content"
33         android:text="@string/bt_unbind" />
34 <TextView android:text="@string/label_find_id"
35     android:layout_width="wrap_content"
36     android:layout_height="wrap_content"/>
37 <EditText android:id="@+id/ed_id"
38     android:layout_width="wrap_content"
39     android:layout_height="wrap_content"
40     android:inputType="number"
41     />
42     <Button
43         android:id="@+id/bt_find"
44         android:layout_width="wrap_content"
45         android:layout_height="wrap_content"
46         android:text="@string/bt_find" />
47     <TextView android:text="@string/label_result"
48     android:layout_width="wrap_content"
49     android:layout_height="wrap_content"/>
50        <TextView 
51            android:id="@+id/find"
52            android:text="@string/find"
53     android:layout_width="wrap_content"
54     android:layout_height="wrap_content"/>
55 
56     
57 
58 </LinearLayout>
主界面

  这是配置文件

Android 学习心得(9)——Service(上)Android 学习心得(9)——Service(上)
 1 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 2     package="com.example.uselocalservice"
 3     android:versionCode="1"
 4     android:versionName="1.0" >
 5 
 6     <uses-sdk
 7         android:minSdkVersion="8"
 8         android:targetSdkVersion="21" />
 9 
10     <application
11         android:allowBackup="true"
12         android:icon="@drawable/ic_launcher"
13         android:label="@string/app_name"
14         android:theme="@style/AppTheme" >
15         <activity android:name="com.example.useLocalService.newAct">
16             <intent-filter >
17                 <action android:name="android.intent.action.MAIN"/>
18                 <category android:name="android.intent.category.LAUNCHER"/>
19             </intent-filter>
20         </activity>
21         <service android:name="com.example.useLocalService.newSer">
22         </service>
23     </application>
24 
25 </manifest>
/useLocalService/AndroidManifest.xml

  字符常量

Android 学习心得(9)——Service(上)Android 学习心得(9)——Service(上)
 1 <resources>
 2 
 3     <string name="app_name">useLocalService</string>
 4 <string name="label_find_id">查询id</string>
 5 <string name="label_result">结果</string>
 6 <string name="find">查询</string>
 7 <string name="bt_start">启动服务</string>
 8 <string name="bt_stop">结束服务</string>
 9 <string name="bt_bind">绑定服务</string>
10 <string name="bt_rebind">运行服务</string>
11 <string name="bt_unbind">解绑服务</string>
12 <string name="bt_find">通过id查名字</string>
13 </resources>
字符常量

 

 

作者:飘0

参考资料:1.androidAPI

    2.Android中Service(服务)详解

    3.Android Service生命周期 Service里面的onStartCommand()方法详解

    4.android Service 服务的生命周期