Android笔记(五十九)Android总结:四大组件——Service篇
什么是服务?
服务(service)是Android中实现程序后台运行的解决方案,适用于去执行那些不需要和用户交互并且还需要长期运行的任务。服务的运行不依赖于任何用户界面。
服务运行在主线程中,所以在service不能用来做一些耗时操作。
服务的用法
1.新建一个继承自Service的类,并实现其抽象方法
2.构建一个Intent
3.使用startService(intent)启动服务
4.使用stopService(intent)停止服务
服务在创建的时候会调用其onCreate()方法,而在每次启动服务的时候都会调用onStartCommand()方法,在服务销毁的时候会调用onDestroy()方法。
Service和Activity的通信
在现实编程中,我们除了要开启关闭Service之外,我们往往还需要获取Service执行的步骤、进度等等,这就需要Service和Activity之间进行通信。
想要Activity和Service之间进行通信,需要使用bindService()和unbindService()方法启动、关闭Service。
bindService()方法有三个参数,分别是:
1.service:通过Intent指定要启动的Service
2.conn:一个ServiceConnection对象,该对用用于监听访问者与Service之间的连接情况。当访问者与Service之间连接成功时将回调该ServiceConnection的onServiceConnectioned方法,当Service所在的宿主进程终止,导致Service与访问者之间断开连接的时回调该ServiceConnection的onServiceDesconnected方法
3.flags:指定绑定时是否自动创建Service(如果该Service还没有创建)。可指定为0(不自动创建),BIND_AUTO_CREATE(自动创建)。
Activity传值给Service
MainActivity.java
package com.example.servicedemo; import com.example.servicedemo.MyService.MyBinder; import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView; public class MainActivity extends Activity implements OnClickListener { private Button start_service_button, stop_service_button, bind_service_button, unbind_service_button,
pass_on_message;
private TextView tvOut; private Intent intent; private MyBinder myBinder; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); start_service_button = (Button) findViewById(R.id.start_service_button);
stop_service_button = (Button) findViewById(R.id.stop_service_button);
bind_service_button = (Button) findViewById(R.id.bind_service_button);
unbind_service_button = (Button) findViewById(R.id.unbind_service_button);
pass_on_message = (Button) findViewById(R.id.pass_on_message);
tvOut = (TextView) findViewById(R.id.tvOut); start_service_button.setOnClickListener(this);
stop_service_button.setOnClickListener(this);
bind_service_button.setOnClickListener(this);
unbind_service_button.setOnClickListener(this);
pass_on_message.setOnClickListener(this);
} @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.start_service_button:
start();
break;
case R.id.stop_service_button:
stop();
break;
case R.id.bind_service_button:
bind();
break;
case R.id.unbind_service_button:
unbind();
break;
case R.id.pass_on_message:
passOnMessage();
break; }
} // 传递数据
private void passOnMessage() {
myBinder.setData("BBBBB"); } // 解除绑定Service
private void unbind() {
Intent intent = new Intent(this, MyService.class);
Log.d("TTTT", "===========点击了unbind按钮============");
unbindService(conn);
} // 绑定启动service
private void bind() {
Intent intent = new Intent(this, MyService.class);
Log.d("TTTT", "===========点击了bind按钮============");
bindService(intent, conn, BIND_AUTO_CREATE);
} // 使用stopService关闭Service
private void stop() {
Intent intent = new Intent(this, MyService.class);
Log.d("TTTT", "===========点击了stop按钮============");
stopService(intent);
} // 使用startService启动Service
private void start() {
Intent intent = new Intent(this, MyService.class);
Log.d("TTTT", "===========点击了start按钮============");
startService(intent); } ServiceConnection conn = new ServiceConnection() { @Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub } @Override
public void onServiceConnected(ComponentName name, IBinder service) {
myBinder = (MyBinder) service; }
};
}
MyService.java
package com.example.servicedemo; import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log; public class MyService extends Service { private String data = "AAAAA"; @Override
public IBinder onBind(Intent intent) {
Log.d("TTTT", "IBind方法运行了...");
return new MyBinder();
} @Override
public void onCreate() {
Log.d("TTTT", "onCreate方法运行了...");
new Thread(new Runnable() {
@Override
public void run() {
int j = 0; for (int i = 0; i < 30; i++) {
try {
j++; String str = j + ":" + data;
Log.d("TTTT", str); Thread.sleep(1000 * 1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
super.onCreate();
} @Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
Log.d("TTTT", "onStart方法运行了...");
} @Override
public int onStartCommand(Intent intent, int flags, int startId) { Log.d("TTTT", "onStartCommand方法运行了..."); return super.onStartCommand(intent, flags, startId);
} @Override
public void onDestroy() {
super.onDestroy();
Log.d("TTTT", "onDestroy方法运行了...");
} @Override
public boolean onUnbind(Intent intent) {
Log.d("TTTT", "onUnbind方法运行了...");
return super.onUnbind(intent);
} public class MyBinder extends Binder {
public void setData(String str) {
data = str;
} public MyService getService() {
return MyService.this;
}
}
}
activity_main.xml
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.servicedemo.MainActivity" > <TextView
android:id="@+id/tvOut"
android:layout_width="match_parent"
android:layout_height="wrap_content" /> <Button
android:id="@+id/start_service_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="开启服务" /> <Button
android:id="@+id/stop_service_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="关闭服务" /> <Button
android:id="@+id/bind_service_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="绑定服务" /> <Button
android:id="@+id/unbind_service_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="解除绑定" /> <Button
android:id="@+id/pass_on_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="传递数据" /> </LinearLayout>
Service传值给Activity
MainActivity.java
package com.example.passupmessageforservice; import com.example.passupmessageforservice.MyService.Callback;
import com.example.passupmessageforservice.MyService.MyBinder; import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView; public class MainActivity extends Activity implements OnClickListener { private Button bt_bindService, bt_unbindService, bt_sync;
private TextView showtext;
private EditText et_str; private Intent intent; private MyBinder myBinder; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initView(); bt_bindService.setOnClickListener(this);
bt_unbindService.setOnClickListener(this);
bt_sync.setOnClickListener(this);
} // 初始化view组件
private void initView() {
bt_bindService = (Button) findViewById(R.id.bt_bindService);
bt_unbindService = (Button) findViewById(R.id.bt_unbindService);
bt_sync = (Button) findViewById(R.id.bt_sync);
showtext = (TextView) findViewById(R.id.showtext);
et_str = (EditText) findViewById(R.id.et_str);
} // 响应点击事件
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_bindService:
bind();
break;
case R.id.bt_unbindService:
unbind();
break;
case R.id.bt_sync:
sync();
break;
}
} // 绑定服务
private void bind() {
Log.d("TTTT", "=========执行bind方法=========");
intent = new Intent(this, MyService.class);
bindService(intent, conn, BIND_AUTO_CREATE);
} // 解除绑定
private void unbind() {
Log.d("TTTT", "=========执行unbind方法=========");
unbindService(conn);
} // 同步数据方法
private void sync() {
myBinder.setData(et_str.getText().toString());
} ServiceConnection conn = new ServiceConnection() { @Override
public void onServiceDisconnected(ComponentName name) {
Log.d("TTTT", "=========执行onServiceDisconnected方法========="); } @Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d("TTTT", "=========执行onServiceConnected方法=========");
myBinder = (MyBinder) service;
myBinder.getService().setCallback(new Callback() { public void change(String str) {
Log.d("TTTT", "~~~~~");
Message msg = new Message();
msg.obj = str;
handler.sendMessage(msg);
}
});
}
}; Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
String str = (String) msg.obj;
showtext.setText(str);
};
}; }
MyService.java
package com.example.passupmessageforservice; import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log; public class MyService extends Service { private String logStr = "AAAA"; private Callback callback = null; private boolean status = false; @Override
public IBinder onBind(Intent intent) {
Log.d("TTTT", "~~~~~~~~~~~~执行onBind方法~~~~~~~~~~~~");
return new MyBinder();
} @Override
public boolean onUnbind(Intent intent) {
Log.d("TTTT", "~~~~~~~~~~~~执行onUnbind方法~~~~~~~~~~~~");
status = true;
return super.onUnbind(intent);
} @Override
public void onCreate() {
super.onCreate(); new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 15; i++) {
if (!status) { if (callback != null) {
callback.change(i + ":" + logStr);
Log.d("TTTT", "================================");
} try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}).start(); Log.d("TTTT", "~~~~~~~~~~~~执行onCreate方法~~~~~~~~~~~~");
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("TTTT", "~~~~~~~~~~~~执行onStartCommand方法~~~~~~~~~~~~");
return super.onStartCommand(intent, flags, startId);
} @Override
public void onDestroy() { Log.d("TTTT", "~~~~~~~~~~~~执行onDestroy方法~~~~~~~~~~~~");
super.onDestroy();
} public class MyBinder extends Binder {
public void setData(String str) {
logStr = str;
} public MyService getService() {
return MyService.this;
}
} public interface Callback {
void change(String str);
} public Callback getCallback() {
return callback;
} public void setCallback(Callback callback) {
this.callback = callback;
} }
activity_main.xml
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.passupmessageforservice.MainActivity" > <EditText
android:id="@+id/et_str"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="输入要传入的文字" /> <Button
android:id="@+id/bt_bindService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="绑定服务" /> <Button
android:id="@+id/bt_unbindService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="解除绑定" /> <Button
android:id="@+id/bt_sync"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="同步数据" /> <TextView
android:id="@+id/showtext"
android:layout_width="match_parent"
android:layout_height="wrap_content" /> </LinearLayout>
Service的生命周期
Service的生命周期,从创建到销毁,有两条不同的路径。
直接启动
使用startService()启动Service,初次启动会先调用onCreate()方法,然后调用onStartCommand()方法,创建Service之后,之后不会再调用onCreate()方法
这种Service可以无限的运行下去,必须调用stopSelf()方法或者其他组件调用stopService()方法来停止它
停止时会调用其onDestroy()方法来销毁这个Service
绑定启动
被绑定的Service是当其他组件调用bindService来创建的
初次绑定会调用onCreate()方法,之后便不会再调用
紧接着会调用onBind()方法
当别的组件调用unbindService()时候,会调用Service的unbind方法,紧接着调用onDestroy()方法。

Android笔记(五十九)Android总结:四大组件——Service篇的更多相关文章
- Android笔记(六十九) 仿微信界面(一)
综合之前的Fragment和自定义组件的知识,实现微信界面 MainActivity.java package cn.lixyz.test; import android.app.Acti ...
- Android笔记(十九) Android中的Fragment
通常我们使用Activity来展示界面,但是在手机上界面可能显示的很好看,但在平板上,因为平板的屏幕非常大,手机的界面放在平板上可能会出现控件被拉长.控件之间间距变大等问题.为了更好的体验效果,在Ac ...
- Android笔记二十四.Android基于回调的事件处理机制
假设说事件监听机制是一种托付式的事件处理,那么回调机制则与之相反,对于基于回调的事件处理模型来说,事件源和事件监听器是统一的,或者说事件监听器全然消失了,当用户在GUI控件上激发某个事件时,控 ...
- Android笔记(六十六) android中的动画——XML文件定义属性动画
除了直接在java代码中定义动画之外,还可以使用xml文件定义动画,以便重用. 如果想要使用XML来编写动画,首先要在res目录下面新建一个animator文件夹,所有属性动画的XML文件都应该存放在 ...
- Android笔记(六十四) android中的动画——补间动画(tweened animation)
补间动画就是只需要定义动画开始和结束的位置,动画中间的变化由系统去补齐. 补间动画由一下四种方式: 1.AplhaAnimation——透明度动画效果 2.ScaleAnimation ——缩放动画效 ...
- Android笔记(十) Android中的布局——表格布局
TableLayout运行我们使用表格的方式来排列控件,它的本质依然是线性布局.表格布局采用行.列的形式来管理控件,TableLayout并不需要明确的声明包含多少行多少列,而是通过添加TableRo ...
- 论文阅读笔记五十九:Res2Net: A New Multi-scale Backbone Architecture(CVPR2019)
论文原址:https://arxiv.org/abs/1904.01169 摘要 视觉任务中多尺寸的特征表示十分重要,作为backbone的CNN的对尺寸表征能力越强,性能提升越大.目前,大多数多尺寸 ...
- Android Studio(五):修改Android Studio项目包名
Android Studio相关博客: Android Studio(一):介绍.安装.配置 Android Studio(二):快捷键设置.插件安装 Android Studio(三):设置Andr ...
- Android实训案例(六)——四大组件之一BroadcastReceiver的基本使用,拨号,短信,SD卡,开机,应用安装卸载监听
Android实训案例(六)--四大组件之一BroadcastReceiver的基本使用,拨号,短信,SD卡,开机,应用安装卸载监听 Android中四大组件的使用时重中之重,我这个阶段也不奢望能把他 ...
随机推荐
- WebViewJavascriptBridge js跟app的交互框架
https://github.com/marcuswestin/WebViewJavascriptBridge 参考: https://www.cnblogs.com/LiLihongqiang/p/ ...
- [LeetCode] 40. Combination Sum II 组合之和 II
Given a collection of candidate numbers (candidates) and a target number (target), find all unique c ...
- ue4读取灰度图生成三维地形mesh
转自:https://www.cnblogs.com/gucheng/p/10116857.html 新建ue c++工程. 在Build.cs中添加"ProceduralMeshCompo ...
- 【嵌入式硬件Esp32】安装MQTT服务器(Windows) 并连接测试
对于不知道MQTT的肯定会问MQTT是干什么的....... 现在我有一个项目需求, 看到这个项目第一想法肯定需要一个服务器,所有的wifi设备和手机都去连接这个服务器,然后服务器进行信息的中转,类似 ...
- 【ARM-Linux开发】ubuntu查看文件大小
使用Linux命令df 和du,df 但是df只能查看一级文件夹大小.使用比例.档案系统及其挂入点,但对文件却无能为力.du可以查看文件及文件夹的大小.所以基本上是两者配合使用. 一 df h参数, ...
- Docker虚拟化
1. Docker虚拟化特点 跟传统VM比较具有如下优点: 操作启动快 运行时的性能可以获取极大提升,管理操作(启动,停止,开始,重启等等) 都是以秒或毫秒为单位的. 轻量级虚拟化 你会拥有足够的“操 ...
- python的进修之路
PYTHON目录篇 本篇主要在个人学习python中的一些总结性的总线,包括python的基础,python的基础进阶,除了帮助和我一样学习python的同学,也是对自己的一种要求! python基础 ...
- LeetCode 445. 两数相加 II(Add Two Numbers II)
445. 两数相加 II 445. Add Two Numbers II 题目描述 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个 ...
- JVM——java内存模型和线程
概述 计算机的运算速度与它的存储和通信子系统速度的差距太大,大量的时间都花费在磁盘I/O.网络通信或者数据库访问上.我们当然不希望处理器大部分时间都处于等待其他资源的状态,要通过一些“手段”去把处理器 ...
- html2canvas以及domtoimage的使用踩坑总结
前言 首先做个自我介绍,我是成都某企业的一名刚刚入行约一年的前端,在之前的开发过程中,遇到了问题,也解决了问题,但是在下一次解决相同问题的时候,只对这个问题有一丝丝的印象,还需要从新去查找,于是,我注 ...