Android学习总结——Service组件

从Service的启动方式上,可以将Service分为Started Service和Bound Service。在使用Service时,要想系统能够找到此自定义Service,无论哪种类型,都需要在AndroidManifest.xml中声明:

<service android:name=".MyService">

一:StartService方式启动服务

Started Service相对比较简单,通过context.startService(Intent serviceIntent)启动Service,context.stopService(Intent serviceIntent)停止此Service。

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.servicetest">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".MyService">

        </service>
    </application>

</manifest>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.servicetest.MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="启动服务"
        android:id="@+id/btn_StartService" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="停止服务"
        android:id="@+id/btn_StopService" />
</LinearLayout>
MainActivity:
package com.example.servicetest;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    private Button startService;
    private Button stopService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startService=(Button)findViewById(R.id.btn_StartService);
        stopService=(Button) findViewById(R.id.btn_StopService);

        startService.setOnClickListener(this);
        stopService.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_StartService:
                //启动服务
                Intent intentStart=new Intent(MainActivity.this,MyService.class);
                startService(intentStart);
                break;
            case R.id.btn_StopService:
                //停止服务
                Intent intentStop=new Intent(MainActivity.this,MyService.class);
                stopService(intentStop);
                break;
        }
    }
}
MyService:
package com.example.servicetest;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by xch on 2016/9/5.
 */
public class MyService extends Service{

    private boolean flag=true;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i("tag","服务被创建!");

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i("tag","服务被销毁!");
        new MyThread().setFlagFalse();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        new MyThread().start();

        return super.onStartCommand(intent, flags, startId);
    }

    class MyThread extends Thread{
        public void setFlagFalse(){
            flag=false;
        }
        @Override
        public void run() {
            super.run();

            while (flag){
                //每隔一秒钟打印当前时间一次
                //设置时间打印格式
                SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//24小时制
                Date date=new Date();
                String time=sdf.format(date);
                Log.i("date",time);
                try {
                    //沉睡1秒
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

二. BoundService方式启动服务

bindService启动流程: context.bindService()  ——> onCreate()  ——> onBind()  ——> Service running  ——> onUnbind()  ——> onDestroy()  ——> Service stop

MainActivity:
package com.example.servicetest2;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    private Button bindService,unBindService;
    private Intent intent;
    private MyServiceConn conn=new MyServiceConn();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        bindService=(Button)findViewById(R.id.btn_BindService);
        unBindService=(Button)findViewById(R.id.btn_UnBindService);

        bindService.setOnClickListener(this);
        unBindService.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_BindService:
                intent=new Intent(MainActivity.this,MyService.class);
                bindService(intent,conn, Context.BIND_AUTO_CREATE);
                break;
            case R.id.btn_UnBindService:
                intent=new Intent(MainActivity.this,MyService.class);
                unbindService(conn);
                break;
        }
    }
    private class MyServiceConn implements ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
           //在服务绑定成功的时候执行
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
           //当服务所在的进程被杀死,或崩溃的时候执行
        }
    }
}
MyService:
package com.example.servicetest2;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by xch on 2016/9/7.
 */
public class MyService extends Service {
    private boolean flag=true;
    private MyThread thread=new MyThread();

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        thread.start();
        return null;
    }

    @Override
    public void onCreate() {
        Log.i("service","服务被创建!");
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i("service","服务被销毁!");
        thread.setFlagFalse();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    class MyThread extends Thread{
        public void setFlagFalse(){
            flag=false;
        }

        @Override
        public void run() {
            super.run();
            while (flag){
                Date date=new Date();
                SimpleDateFormat sdf=new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
                Log.i("date",sdf.format(date));
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}

三.Service与Activity之间通讯

BoundService可以实现,但是startService没有这个特点。这里需要注意的是,利用bindService启动的Service无法获取这个Service对象,所以这里需要在Service中将对象返回,既然有返回就需要接收。so,看代码:

MyService:
package com.example.servicetest2;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by xch on 2016/9/7.
 */
public class MyService extends Service {
    private boolean flag=true;
    private MyThread thread;
    private String format="yyyy-mm-dd HH:mm:ss";

    //更改系统时间的输出格式
    public void setFormat(String format){
        this.format=format;
    }

    public void changeFormat(String format){
        if(thread!=null){
            //调用方法,更改时间输出格式
            setFormat(format);
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        thread.start();
        //将代理类返回回去
        return new ServiceBinder();
    }

    @Override
    public void onCreate() {
        Log.i("service","服务被创建!");
        thread=new MyThread();
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i("service","服务被销毁!");
        thread.setFlagFalse();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    class MyThread extends Thread{
        public void setFlagFalse(){
            flag=false;
        }

        @Override
        public void run() {
            super.run();
            while (flag){
                Date date=new Date();
                SimpleDateFormat sdf=new SimpleDateFormat(format);
                Log.i("date",sdf.format(date));
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    }

    /**
     * 当前服务的代理类,即可使用changeFormat()方法
     * 需要通过IBinder将这个代理类返回回去,即onBinder()方法
     */
    public class ServiceBinder extends Binder{
        public void changeServiceBinder(String format){
            if(thread!=null){
                changeFormat(format);
            }
        }

    }
}

这里需要在service中定义一个代理类,并利用onBinder()方法返回去。

MainActivity:

package com.example.servicetest2;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    private Button bindService,unBindService,changeFormat;
    private Intent intent;
    private MyServiceConn conn=new MyServiceConn();
    //接收到的service对象
    private MyService.ServiceBinder serviceBinder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        bindService=(Button)findViewById(R.id.btn_BindService);
        unBindService=(Button)findViewById(R.id.btn_UnBindService);
        changeFormat=(Button)findViewById(R.id.btn_changeFormat);

        bindService.setOnClickListener(this);
        unBindService.setOnClickListener(this);
        changeFormat.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_BindService:
                intent=new Intent(MainActivity.this,MyService.class);
                bindService(intent,conn, Context.BIND_AUTO_CREATE);
                break;
            case R.id.btn_UnBindService:
                intent=new Intent(MainActivity.this,MyService.class);
                unbindService(conn);
                break;
            case R.id.btn_changeFormat:
                serviceBinder.changeServiceBinder("HH:mm:ss");
                break;
        }
    }
    private class MyServiceConn implements ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
           //在服务绑定成功的时候执行,同时接收到了IBinder对象(类型为代理类对象,因为onBinder方法返回了代理类对象)
            serviceBinder= (MyService.ServiceBinder) service;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
           //当服务所在的进程被杀死,或崩溃的时候执行
        }
    }
}

这里实现了ServiceConnection接口的自定义类需要实现如上两个方法,其中onServiceConnected(ComponentName name, IBinder service)方法能获取onBinder()返回的service对象。

 结果:






时间: 2024-10-07 17:21:13

Android学习总结——Service组件的相关文章

android学习--TabHost选项卡组件

TabHost是一种非常实用的组件,TabHost可以很方便地在窗口上放置多个标签页,每个标签页获得了一个与外部容器相同大小的组件摆放区域.在手机系统的应用类似"未接电话"."已接电话"."呼出电话"等. 1 . TabHost提供了两个方法来创建选项卡.添加选项卡 newTabSpec(String tag)  : 创建选项卡 addTab(TabHost.TabSpec  tabSpec) : 添加选项卡 2.TabHost 切换选项卡触发的

【Android基础】-Service组件使用详解

Service是Android四大组件之一,它与Activity的区别是:它一直在后台运行,没有前台界面.一旦Service被启动起来后,他就跟Activity一样,完全具有自己的生命周期. 一.创建Service,定义一个继承Service的子类 Service中定义了一系列生命周期方法,如下: IBinder onBind(Intent intent):该方法是Service必须实现的方法.该方法返回一个IBinder对象,应用程序可以通过该对象与Service组件通信. void onCr

Android学习之Service(1)---&gt;Started方式

界面退出后进程程序还在运行,不会被杀死,如音乐播发器.后台下载等 注:本文只讨论Started方式 main.xml代码分析 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical"

我有一壶酒 Android学习之Service(1)---&gt;BinderService方式

本文只讨论扩展Binder类 创建一个Binder.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_p

android学习笔记 Service

Service(服务): 长期后台运行的没有界面的组件 android应用什么地方需要用到服务? 天气预报:后台的连接服务器的逻辑,每隔一段时间获取最新的天气信息.股票显示:后台的连接服务器的逻辑,每隔一段时间获取最新的股票信息.mp3播放器: 后台长期的播放音乐. ---------------------------------------------------------------------------------new Thread(){}.start(); 子线程没有界面,也是长

Android 学习笔记 6 组件通信及广播消息(一)

Intent的概念 Intent的官方解释是“An Intent is a messaging object you can use to request an action from another app component. ”这里的app component就是指安卓activity,service,contentprovider,broadcastreceiver四大组件.不同的intent可以使这些组件产生相应的动作,为这些组件之间提供了交互能力.那么这个“messaging obj

Android 学习笔记 Service服务与远程通信...(AIDL)

PS:这一章节看的我有几分迷茫,不是很容易理解...不过还好总算是明白了一大半了...基本的迷惑是解决了... 学习内容: 1.跨应用启动服务... 2.跨应用绑定服务... 3.跨应用实现通信... 由于5.0版本之前和5.0版本之后是有很大的区别的,因此我都会在这里进行具体的介绍... 1.跨应用启动服务...   跨应用启动服务,其实就是多个应用程序之间产生一种沟通关系,应用程序之间可以进行通信或者是完成一些其他的互动,总而言之,就是在我本身的应用程序中去启动其他应用程序的某个服务,这就完

Android 学习笔记 7 组件通信及广播消息(二)

Intent隐式启动Activity 隐式启动的好处在于不需要在第一个组件中指明需要启动另外的哪一个组件,而由Android系统来决定,这样有利于降低组件之间的耦合度. 选择隐式启动Activity,Android系统会在程序运行时解析Intent,并根据一定的规则对Intent和组件进行匹配,使Intent上的action.data和category与目标Activity吻合.匹配的组件可以是程序本身的Activity,也可以是Android系统内置的Activity,还可以是第三方应用程序提

Android学习笔记—开发组件3

通知类组件 (1)Toast组件:一般出现在屏幕下方,黑色边框,显示一段时间自动消失,不会打断用户操作. 场景:下载完成.更新完成.充电结束.安装成功等 Toast.makeText(this,"下载完成",Toast.LENGTH_SHORT).show(); (2)Notification组件:状态栏上的通知 特性:具有全局效果的通知,时效性不强. 场景:短信.未接电话.下载等. //获取通知管理器NotificationManager对象 mNitificationManager