<Android基础> (十)Service Part 2 基本用法

10.3 Service的基本用法

10.3.1 定义一个服务

New——>Service

public class MyService extends Service {
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

重写3个方法

   //服务创建时调用@Override
    public void onCreate() {
        super.onCreate();
    }
//每次服务启动时调用
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }
//服务销毁时调用
    @Override
    public void onDestroy() {
        super.onDestroy();
    }

在AndroidManifest.xml中已经自动注册好

<service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true"></service>

10.3.2 启动和停止服务

修改activity_main中的代码,在布局中加两个按钮用于启动和停止服务

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/start_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start Service"/>

    <Button
        android:id="@+id/stop_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Stop Service"/>

</LinearLayout>

修改MainActivity中的代码,构建Intent对象来启动和停止服务

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button startService = (Button)findViewById(R.id.start_service);
        Button stopService = (Button)findViewById(R.id.stop_service);
        startService.setOnClickListener(this);
        stopService.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.start_service:
                Intent startIntent = new Intent(this, MyService.class);
                startService(startIntent);
                break;
            case R.id.stop_service:
                Intent stopIntent = new Intent(this, MyService.class);
                stopService(stopIntent);
                break;
        }
    }
}

在MyService中增加打印日志

@Override
    public void onCreate() {
        super.onCreate();
        Log.d("MyService","onCreate executed");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("MyService","onStartCommand executed");
        return super.onStartCommand(intent, flags, startId);

    }

    @Override
    public void onDestroy() {
        Log.d("MyService","onDestroy executed");
        super.onDestroy();
    }

运行程序,点击按钮

10.3.3 活动和服务进行通信

活动和服务之间通信需要借助onBind()方法。

比如希望在MyService中提供一个下载功能,然后在活动中决定何时开始下载,以及随时查看下载进度。

创建一个专门的Binder对象来对下载功能进行管理。修改MyService中的代码。

public class MyService extends Service {

    private DownloadBinder mBinder = new DownloadBinder();

    class DownloadBinder extends Binder {
        public void startDownload(){
            Log.d("MyService","startDownload executed");
        }
        public int getProgress(){
            Log.d("MyService","getProgress executed");
            return 0;
        }
    }
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
      1
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("MyService","onCreate executed");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("MyService","onStartCommand executed");
        return super.onStartCommand(intent, flags, startId);

    }

    @Override
    public void onDestroy() {
        Log.d("MyService","onDestroy executed");
        super.onDestroy();
    }
}

在activity_main中添加两个按钮用于绑定和解绑服务

    <Button
        android:id="@+id/bind_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Bind Service"/>

    <Button
        android:id="@+id/unbind_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Unbind Service"/>

修改MainActivity中的代码

当活动和服务绑定后,就可以调用该服务中Binder提供的方法了。

首先创建一个ServiceConnection的匿名类,在里面重写onServiceConnected()方法和onServiceDisconnected()方法,分别在活动与服务成功绑定以及活动与服务的连接断开的时候调用。

在onServiceConnected()方法中调用了DownloadBinder的startDownload()和getProgress()方法。

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private MyService.DownloadBinder downloadBinder;
    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            downloadBinder = (MyService.DownloadBinder) service;
            downloadBinder.startDownload();
            downloadBinder.getProgress();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button startService = (Button)findViewById(R.id.start_service);
        Button stopService = (Button)findViewById(R.id.stop_service);
        Button bindService = (Button)findViewById(R.id.bind_service);
        Button unbindService = (Button)findViewById(R.id.unbind_service);
        startService.setOnClickListener(this);
        stopService.setOnClickListener(this);
        bindService.setOnClickListener(this);
        unbindService.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.start_service:
                Intent startIntent = new Intent(this, MyService.class);
                startService(startIntent);
                break;
            case R.id.stop_service:
                Intent stopIntent = new Intent(this, MyService.class);
                stopService(stopIntent);
                break;
            case R.id.bind_service:
                Intent bindIntent = new Intent(this, MyService.class);
                bindService(bindIntent, connection, BIND_AUTO_CREATE); //绑定服务
                break;
            case R.id.unbind_service:
                unbindService(connection);  //解绑服务
                break;
            default:
                break;
        }
    }
}

运行程序:

10.4 Service的生命周期

10.5 Service的更多技巧

10.5.1 使用前台服务

希望服务可以一直保持运行状态,而不会由于系统内存不足的原因导致被回收,可以考虑使用前台服务。

前台服务和普通服务最大的区别在于,它会有一个正在运行的图标在系统的状态栏显示,下拉状态栏可以看到更加详细的信息,非常类似于通知的效果。

修改MyService中的代码

 @Override
    public void onCreate() {
        super.onCreate();
        Log.d("MyService","onCreate executed");
        Intent intent =  new Intent(this,MainActivity.class);
        PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);
        Notification notification = new NotificationCompat.Builder(this,"default")
                .setContentTitle("This is content title")
                .setContentText("This is content text")
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.mipmap.ic_launcher)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(),
                        R.mipmap.ic_launcher))
                .setContentIntent(pi)
                .build();
        startForeground(1, notification);
    }

类似于创建通知的方法。

运行程序:

10.5.2 使用IntentService

服务中的代码都是默认运行在主线程当中的,如果直接在服务里去处理一些耗时的逻辑,就很容易出现ANR(Application Not Responding/应用程序未响应)的情况。

Android专门提供了一个IntentService类,这个类很好的解决了忘记开启线程或忘记停止服务。

新建一个类继承IntentService

public class MyIntentService extends IntentService {
    public MyIntentService(){
        super("MyIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        //打印当前线程的id
        Log.d("MyIntentService", "Thread id is " + Thread.currentThread().getId());
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("MyIntentService","onDestroy executed");  //打印日志以证明服务停止
    }
}

在activity_main中添加一个Button

    <Button
        android:id="@+id/start_intent_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start IntentService"/>

修改MainActivity中的代码

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private MyService.DownloadBinder downloadBinder;
    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            downloadBinder = (MyService.DownloadBinder) service;
            downloadBinder.startDownload();
            downloadBinder.getProgress();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button startService = (Button)findViewById(R.id.start_service);
        Button stopService = (Button)findViewById(R.id.stop_service);
        Button bindService = (Button)findViewById(R.id.bind_service);
        Button unbindService = (Button)findViewById(R.id.unbind_service);
        Button startIntentService = (Button)findViewById(R.id.start_intent_service);
        startService.setOnClickListener(this);
        stopService.setOnClickListener(this);
        bindService.setOnClickListener(this);
        unbindService.setOnClickListener(this);
        startIntentService.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.start_service:
                Intent startIntent = new Intent(this, MyService.class);
                startService(startIntent);
                break;
            case R.id.stop_service:
                Intent stopIntent = new Intent(this, MyService.class);
                stopService(stopIntent);
                break;
            case R.id.bind_service:
                Intent bindIntent = new Intent(this, MyService.class);
                bindService(bindIntent, connection, BIND_AUTO_CREATE); //绑定服务
                break;
            case R.id.unbind_service:
                unbindService(connection);  //解绑服务
                break;
            case R.id.start_intent_service:
                Log.d("MainActivity", "Thread id is " + Thread.currentThread().getId());
                Intent intentService = new Intent(this, MyIntentService.class);
                startService(intentService);
                break;
            default:
                break;
        }
    }
}

最后在AndroidManifest中注册

 <service android:name=".MyIntentService"/>

运行程序:

MyIntentService和MainActivity所在的线程id不一样,而且onDestroy()方法也得到了执行,说明MyIntentService在运行完毕确实自动停止了,集开启线程和自动停止于一身。

原文地址:https://www.cnblogs.com/HarSong13/p/10833051.html

时间: 2024-08-29 13:31:20

<Android基础> (十)Service Part 2 基本用法的相关文章

android 基础一 &lt;Service&gt;

1. 创建一个service: public class MyService extends Service {} 2.在清单中申明service<application> <service        android:name=".MyService"        android:enabled="true"        android:exported="true">    </service><

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

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

android学习十九(WebView的用法)

android提供了一个WebView控件,借助它我们就可以在自己的应用程序中嵌入一个浏览器,从而轻松的展示各种各样的网页.下面来学习下简单的用法.新建一个WebViewTest项目,然后修改activity_main.xml中的代码,如下所示: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/

Android基础(五) Service全解析----看不见的Activity

一.服务的介绍: 作为Android四大组件之中的一个,Service(服务)也常常运用于我们的日常使用中,它与Activity的差别在于:Service一直在后台执行.没实用户界面.所以绝不会到前台来.但Service被启动起来之后.它就和Activity一样.全然具有自己的生命周期. 在关于程序中是选择用Activity还是Service的一个选择标准就是:假设某个程序组件须要执行时向用户呈现某种用户界面.或者该程序须要与用户交互,就须要使用Activity,否则就该考虑使用Service.

[Android 基础系列]Service、IntentService和习以为常的误解

前言: 也许是低门槛原因,最初接触Android的人写了很多书.博文,创造了一个邪论:Activity就是弄界面的,Service就是弄后台的,进而将"播放音乐"这种演变为"耗时操作",进而演绎成:"耗时的.长时间运行的都需要使用service".只想说:MDZZ! 原意是想全文自己写,但看了一眼API文档,整理的实在是太好了,所以本文会摘录API的内容并结合重点写一点内容. 正文: Service: API文档中的概述如下: A Service

Android 基础 十二 Bitmap的加载和Cache

本章的主题是Bitmap的加载和Cache,主要包含三个方面的内容.首先讲述如何有效地加载一个Bitmap,这是一个很有意义的话题,由于Bitmap的特殊性以及Android对单个应用所施加的内存限制,比如16MB,这导致Bitmap加载的时候很容易出现内存溢出.下面这个异常信息在开发中应该经常遇到: 因此如何高效的加载Bitmap是一个很重要也很容易被开发者或忽视的问题. 接着介绍Android中常用的缓存策略,缓存策略是一种通用的思想,可以用在很多场景中,但是实际开发中经常需要用Bitmap

android学习十八(Service服务的基本用法)

定义一个服务 在项目中定义一个服务,新建一个ServiceTest项目,然后在这个项目中新增一个名为MyService的类,并让它继承自Service,完成后的代码如下所示: package com.jack.servicetest; import android.app.Service; import android.content.Intent; import android.os.IBinder; public class MyService extends Service { @Over

Android基础入门教程——4.2.1 Service初涉

Android基础入门教程--4.2.1 Service初涉 标签(空格分隔): Android基础入门教程 本节引言 好的,我们在前三节中对Android中的Activity进行了研究学习,相信大家获益良多吧! 本节开始我们继续来学习Android中的第二个组件:Service(服务), 好,废话不多说,开始本节内容! 1.线程的相关概念 在开始学习Service之前我们先来了解下线程的一些概念! 1)相关概念: 程序:为了完成特定任务,用某种语言编写的一组指令集合(一组静态代码) 进程:运行

Android基础入门教程——4.2.2 Service进阶

Android基础入门教程--4.2.2 Service进阶 标签(空格分隔): Android基础入门教程 本节引言 上节我们学习了Service的生命周期,以及两种启动Service的两种方法, 本节继续来深入了解Service中的IntentService,Service的使用实例: 前台服务与轮询的实现! 1.IntentService的使用 在上一节后我们已经知道了如何去定义和启动Service,但是如果我们直接把 耗时线程放到Service中的onStart()方法中,虽然可以这样做