zoukankan      html  css  js  c++  java
  • <Android 基础(一)> Service

    介绍

    Service(服务)是一个没有用户界面的在后台运行执行耗时操作的应用组件。其他应用组件能够启动Service,并且当用户切换到另外的应用场景,Service将持续在后台运行。另外,一个组件能够绑定到一个service与之交互(IPC机制),例如,一个service可能会处理网络操作,播放音乐,操作文件I/O或者与内容提供者(content provider)交互,所有这些活动都是在后台进行。
    Service有两种状态,“启动的”和“绑定”。

    使用方法

    看下关于Service两张比较经典的图
    这里写图片描述

    这里写图片描述

    简单实例

    AndroidManifest.xml

       <application
                android:label="@string/app_name"
                android:icon="@drawable/ic_launcher">
    
            <activity
                    android:name=".MyActivity"
                    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=".MyService"
                    android:enabled="true"/>  <!--四大组件都要在AndroidManifest中申明一把 -->
        </application>

    MyActivity.java

    public class MyActivity extends Activity implements View.OnClickListener, ServiceConnection {
        public static String TAG = "MyActivity";
    
        Intent intent;
    
        /**
         * Called when the activity is first created.
         */
        @Override
        public void onCreate(Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            Log.e(TAG, "MyActivity OnCreate");
            intent = new Intent(MyActivity.this, MyService.class);
    
            findViewById(R.id.bt_startservice).setOnClickListener(this);
            findViewById(R.id.bt_stopservice).setOnClickListener(this);
            findViewById(R.id.bt_bindservice).setOnClickListener(this);
            findViewById(R.id.bt_unbindservice).setOnClickListener(this);
        }
        //OnClick事件监听
        public void onClick(View view) {
            Log.e(TAG,"OnClick");
            switch (view.getId()) {
                case R.id.bt_startservice:
                    Log.e(TAG, "start Service");
                    startService(intent);
                    break;
                case R.id.bt_stopservice:
                    stopService(intent);
                    break;
                case R.id.bt_bindservice:
                    bindService(intent, this, Context.BIND_AUTO_CREATE);
                    break;
                case R.id.bt_unbindservice:
                    unbindService(this);
                    break;
            }
        }
    
        @Override //binderService成功后回调,带过来的IBinder可用于和Activity通信
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            Log.e(TAG, "onServiceConnected");
        }
    
        @Override //在服务崩溃或被杀死导致的连接中断时被调用
        public void onServiceDisconnected(ComponentName componentName) {
            Log.e(TAG, "onServiceDisconnected");
        }
    }

    MyService.java

    public class MyService extends Service {
        public static String TAG = "MyService";
    
        @Override
        public void onCreate() {
            super.onCreate();
            Log.e(TAG, "MyService onCreate");
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
    
            Log.e(TAG, "onStartCommand");
    
            //用来测试Service是否在后台有运行
            /*new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        Log.e(TAG, "Service is Running ...");
                    }
                }
            }).start();*/
            return super.onStartCommand(intent, flags, startId);
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            Log.e(TAG, "onDestroy");
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            Log.e(TAG, "onBind");
            return new Binder();//new一个binder对象通过onServiceConnected回调,方便通信
        }
    
        @Override
        public boolean onUnbind(Intent intent) {
            Log.e(TAG, "onUnbind");
            return super.onUnbind(intent);
        }
    
        @Override  //onRebind的调用时机和onUnbind的返回值有关系
        public void onRebind(Intent intent) {
            Log.e(TAG, "onRebind");
            super.onRebind(intent);
        }
    }

    测试结果

    1. 启动服务,停止服务
      这里写图片描述

    2. 绑定服务,解绑服务
      这里写图片描述

    3. 启动服务,绑定服务,解绑服务
      这里写图片描述
      注意:这里最后Service是没有onDestory的

    4. 启动服务,绑定服务,解绑服务,停止服务
      这里写图片描述

    5. Binder使用,这个很关键
    MyService.java中修改

        public IBinder onBind(Intent intent) {
            Log.e(TAG, "onBind");
            return new MyBinder();
        }
       class MyBinder extends Binder {
            public void sayHello() {
                Log.e(TAG,"I am a binder, hi");
            }
        }

    MyActivity.java中修改

        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            Log.e(TAG, "onServiceConnected");
            MyService.MyBinder binder = (MyService.MyBinder) iBinder;
            ((MyService.MyBinder) iBinder).sayHello();
        }

    然后执行:绑定服务,解绑服务
    这里写图片描述

    通过这个Binder,再加上Callback,可以实现对Service内部状态的监听
    先定义一个接口,然后创建get与set,在onBinder方法中定义一个线程不停的发送数据

    public interface Callback() {
        public void onDateChanged(String data) {
        }
    }
    
    public void setCallback(Callback callback) {
        this.callback =  callback;
    }
    
    public Callback getCallback() {
        return callback;
    }
        public IBinder onBind(Intent intent) {
            Log.e(TAG, "onBind");
    
            running = true;//running通过service的生命周期控制
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while (running) {
                        try {
                            Thread.sleep(1000);
                            i++;
                            String str = "send: " + i ;
                            callback.onDateChanged(str);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        Log.e(TAG, "Service is Running ... ");
                    }
                }
            }).start();
            return new MyBinder();
        }

    然后在MyBinder类中定义一个getService方法

     public MyService getSetvice() {
         return MyService.this;
     }

    然后在onServiceConnected中

    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            Log.e(TAG, "onServiceConnected");
            MyService.MyBinder binder = (MyService.MyBinder) iBinder;
            MyService myservice = binder.getService();
            myservice.setCallback(new MyService.Callback() {
                @Override
                public void onDateChanged(String str) {//非UI线程无法直接更新UI,需要通过handler机制
                    Message msg = new Message();
                    msg.arg1 = 1;
                    Bundle bundle = new Bundle();
                    bundle.putString("data", str);
                    msg.setData(bundle);
                    handler.sendMessage(msg);
                }
            });
        }

    通过这种方式就可以实现Service和Activity的通信工作,不难看出,Binder在其中起着非常重要的角色。
    Android中进程间通信,从JAVA到C++基本上都是用Binder来实现的,上层使用的AIDL下一篇介绍一下,

    这个系列只关注基础内容,希望可以坚持下来。

  • 相关阅读:
    react文本溢出hover气泡显示全部文本——JS判断文本溢出
    ecosystem.config
    git删除中间某次提交
    HTML5 新元素
    HTML5存储
    简述LVS(Linux虚拟服务器)
    简述线程池
    网络协议基础
    JVM常用性能检测工具
    线程间的“通信”方法
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6467205.html
Copyright © 2011-2022 走看看