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


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

      service生命周期图

     

      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调用

      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调用源码

      这是界面

     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>
    主界面

      这是配置文件

     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

      字符常量

     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 服务的生命周期

  • 相关阅读:
    mysql学习笔记——建表需满足的三大范式
    mysql学习笔记——对数据记录查询操作的补充(单表内查询)
    mysql学习笔记——对数据表中记录的操作
    转载----- mysql 五大约束
    mysql笔记------对数据表操作
    c语言中static的用法
    解决Android抽屉被击穿问题
    解决ScrollView与ListView事件冲突
    使用Loader实时查询本地数据库用法
    Android中实现两次点击返回键退出本程序
  • 原文地址:https://www.cnblogs.com/lingzhishitu/p/4466979.html
Copyright © 2020-2023  润新知