文档章节

安卓精要:Service

无极客
 无极客
发布于 07/17 00:40
字数 1284
阅读 3
收藏 0

服务

服务是什么

服务可以在后台运行而不依赖于任何用户界面

服务并不是运行在一个独立的进程中,而是依赖于创建服务时所在的应用程序进程

服务业不是运行在一个独立线程中,所有代码都是默认在主线程中运行

也就是说需要我们在服务内部手动创建子线程去执行耗时任务,否则将会阻塞主线程

安卓多线程编程

线程的基本用法

参考Java

在子线程中更新UI

GUI大都是线程不安全的,安卓的UI也一样

也就是说要更新应用程序里的UI元素必须在主线程中进行,否则就会出现异常

我们需要使用Handler来进行同步操作

public class mainActivity extends AppCompatActivity implements View.onClickListener {
    public static final int UPDATE_TEXT = 1 ; 
    private TextView text ;

    private Handler handler = new Handler(){
    
        public void handleMessage(Message msg)
        {
            switch(msg.what)
            {
                case UPDATE_TEXT:
                //进行UI操作
                text.setText("Hello");
                break;
            }
        }
    }

    @Override
    public void onClick(View v)
    {
        switch(v.getId())
        {
            case R.id.change_text:
                new Thread(new Runnable(){
                    @Override
                    public void run(){
                        Message message=new Message();
                        message.what=UPDATE_TEXT;
                        handler.sendMessage(message);
                    }
                }).start();
        }
    }
}

解析异步消息处理机制

Message

message是在线程之间传递的消息,它可以在内部携带少量的信息,用于在 不同线程之间交换数据,Message可以通过what携带数据外 可以使用arg1,arg2字段来携带一些整数型数据 使用obj字段可以携带一个object对象

Handler

消息处理着,用于发送消息和处理消息,发送消息一般用sendMessage(); 最终会传递到handleMessage()中

MessageQueue

消息队列,用于存放所有通过Handler发送的消息,等待被处理

Looper

消息循环,Looper是每个线程中消息队列的管家,调用Looper的loop() 方法后,会进入一个无限循环中,每当发现队列中存在一条消息就将它取出并 传递到Handler的handleMessage()中,每个线程也只会有一个Looper对象

使用AsyncTask

AsyncTask<Params,Progress,Result>

Params 执行Async时传入的参数类型,于后台任务中使用 Progress 可用于表示进度,如整数 Result 任务执行完毕的返回值(可以为void)

class DownloadTask extends AsyncTask<Void, Integer, Boolean> {  
    
    /*
    在主线程中运行
    这个方法会在任务开始执行之前调用
    */  
    @Override  
    protected void onPreExecute() {  
        progressDialog.show();  
    }  
  
    /*
    将在子线程中运行
    */
    @Override  
    protected Boolean doInBackground(Void... params) {  
        try {  
            while (true) {  
                int downloadPercent = doDownload();  
                publishProgress(downloadPercent);  
                if (downloadPercent >= 100) {  
                    break;  
                }  
            }  
        } catch (Exception e) {  
            return false;  
        }  
        return true;  
    }  
  
    /*
    在主线程中运行
    publishProgress()执行之后,该方法在一会儿后被主线程调用
    */  
    @Override  
    protected void onProgressUpdate(Integer... values) {  
        progressDialog.setMessage("当前下载进度:" + values[0] + "%");  
    }  
  
    /*
    在主线程中运行
    后台任务完成后通过return返回时,这个方法就很快会被调用
    返回的数据将传递到此方法中
    */  
    @Override  
    protected void onPostExecute(Boolean result) {  
        progressDialog.dismiss();  
        if (result) {  
            Toast.makeText(context, "下载成功", Toast.LENGTH_SHORT).show();  
        } else {  
            Toast.makeText(context, "下载失败", Toast.LENGTH_SHORT).show();  
        }  
    }  
}  

启动这个任务

new DownloadTask().execute();

服务的基本用法

定义一个服务

服务必须实现Service类

IBinder onBind(Intent intent)是唯一抽象方法,必须实现

onCreate()是服务被创建时调用

onCommand()是服务每次被启动时调用

onDestory()是销毁服务时调用,用于回收资源

服务也必须在AndroidMainfest.xml中进行注册才能生效 但创建服务时Android Studio自动注册它

启动和停止服务

Intent startIntent = new Intentcontext,MyService.class);
startService(startIntent);
    ...
Intent stopIntent = new Intent(context,MyService.class);
stopService(stopIntent);

服务可以调用stopSelf();自己停止下来

startService第一次调用时服务的onCreate()会被调用 而onCommand在startService()任何一次调用时都会被调用

活动和服务通信

实现IBinder onBind(Intent intent)返回一个实现IBinder的对象,该对象 中可以自己定义一些公共方法暴露给外部

服务不是一个普通的对象,它是系统级的组件,要与调用者分离,它在第一次启动时 被系统创建,而以后的启动都只是使用相同的实例,所以它们仅仅通过 Binder与外部进行通讯而不是直接调用服务的

方法

private ABinder aBinder;
private ServiceConnection connection = new ServiceConnection()
{
    
    @Override void onServiceDisconnected(ComponentName name)
    {
        
    }
    
    @Override void onServiceConnected(ComponentName name,IBinder service)
    {
        aBinder=(ABinder)service;
        aBinder.doSthX();
    }
}


Intent bindIntent = new Intent(context,MyService.class);
bindService(bindIntent,connection,BIND_AUTO_CREATE));
//以bind方式启动服务不需要先调用startService();
//同样在服务未创建时,系统会创建服务
unbindService(connection);


aBinder.doSthY();

服务的生命周期

服务的更多技巧

使用前台服务

使用IntentService

public class MyService extends IntentService{
    public MyService()
    {
        super("MyService");
    }
    @Override
    protected void onHandleIntent(Intent intent)
    {
    }
}

IntentService的特殊之处在于,onHandleIntent会在子线程中运行 并且,方法结束时自动回调用onDestory并销毁服务

© 著作权归作者所有

共有 人打赏支持
无极客
粉丝 0
博文 7
码字总数 25385
作品 0
潮州
私信 提问
《Android开发精要》将于2012年3月隆重上市

融合本人多年功力精心写就的《Android开发精要》将于2012年3月隆重上市,作为机械工业出版社2012年的重点图书,全面、重点介绍了Android开发的技术难点和重点。 不同于以实例为主的普通Andro...

苗忠良
2012/01/13
0
9
Android基础再回首——四大组件之Activity、Service俩兄弟

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m366917/article/details/54100085 Android基础再回首——四大组件之Activity、Service俩兄弟 偶尔的回首过去...

Aduroidpc
2017/01/05
0
0
Android四大组件之Service

相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的Android程序员如果连Service都没听说过的话,那确实也太逊了。Service作为Android四大组件之一,在每一个应用程序中都扮演着非...

的书法上的
2014/05/26
0
0
Android 核心分析 之六 -----IPC框架分析 Binder,Service,Se...

我首先从宏观的角度观察Binder,Service,Service Manager,并阐述各自的概念。从Linux的概念空间中,Android的设计Activity托管在不同的的进程,Service也都是托管在不同的进程,不同进程间的...

LiSteven
2013/08/23
0
0
Service 与 Thread 的区别

很多时候,你可能会问,为什么要用 Service,而不用 Thread 呢,因为用 Thread 是很方便的,比起 Service 也方便多了,下面我详细的来解释一下。 1). Thread:Thread 是程序执行的最小单元,...

带梦想一7飞
2014/02/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

当程序员有了中年危机 你会发现你就是个屁

前言 程序员是一个怎样的存在?引用一句鸡汤的名言来说:你以为你用双手改变了世界,实际上是苍老了自己。为什么我今天会抛出这个话题,其实我也是一个懵懂的少年,我也曾经为了成为一名程序...

架构师springboot
4分钟前
0
0
大型网站B2C商城项目实战+MongoDB+Redis+zookeeper+MySQL

本文列出了当今计算机软件开发和应用领域最关键部分,如果你想保证你现在以及未来的几年不失业,那么你最好跟上这些技术的发展。虽然你不必对这十种技术样样精通,但至少应该对它们非常熟悉。...

java知识分子
5分钟前
0
0
大型企业网络系统集成方案如何设计?

网络系统集成是企业实现无纸化办公和即时通讯办公的基础建设,在以生产效率为核心竞争力的市场中,企业想要快速获取信息并有效提高企业工作效率及业务能力,企业网络系统集成是必不可少的,由...

Java干货分享
6分钟前
0
0
Spring应用学习——IOC

1. Spring简介 1. Spring的出现是为了取代EJB(Enterprise JavaBean)的臃肿、低效、脱离现实的缺点。Spring致力于J2EE应用的各层(表现层、业务层、持久层)的解决方案,Spring是企业应用开...

江左煤郎
7分钟前
0
0
用Redis轻松实现秒杀系统

导论 曾经被问过好多次怎样实现秒杀系统的问题。昨天又在CSDN架构师微信群被问到了。因此这里把我设想的实现秒杀系统的价格设计分享出来。供大家参考。 秒杀系统的架构设计 秒杀系统,是典型...

James-
14分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部