黑马程序员技术交流社区
标题: 十年磨一剑【基哥笔记】Android基础—Day08-绑定服务 [打印本页]
作者: allen927 时间: 2015-12-8 08:41
标题: 十年磨一剑【基哥笔记】Android基础—Day08-绑定服务
本帖最后由 allen927 于 2015-12-8 08:55 编辑
同样的课程、老师、就业,更好的学习环境,更低的学习成本!
android基础Day08(绑定服务)
《 如果感觉今天的知识点都会了,可以直接做作业,来进行检测》
•(了解)为什么需要绑定服务 绑定服务就是为了和服务进行通讯
可以调用服务里面的方法
•(掌握)绑定服务调用服务方法的流程
•(掌握)绑定服务抽取接口
接口的抽取:有什么样的行为,就抽取什么样的方法。
•(掌握)绑定本地服务 案例
总结
代码
1 订阅接口
/**
* 接口
*@author apple
*
*/
public interface IStudentListener {
//根据学号查询学生的姓名
publicString queryNameById(int id);
}
2 服务
public class MyService extends Service {
privateString[] names = new String[]{"张学友","刘德华","黎明","郭富城"};
//增强版IBinder(真实的对象)
private MyBinder ibinder = new MyBinder();
@Override
public IBinder onBind(Intent intent) {
return ibinder;
}
//创建一个增强版的IBinder类
private class MyBinder extends Binder implementsIStudentListener{
@Override
publicString queryNameById(int id) {
//id只能是1 到4
if(id<= 0 || id > names.length){
return"苍姐姐";
}else{
returnnames[id-1];
}
}
}
}
3 客户端
public class MainActivity extends Activity{
privateEditText et_id;
privateButton bt_query;
privateTextView tv_name;
privateMyServiceConnection conn;
privateIStudentListener iStudentListener;
@Override
protectedvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_id= (EditText) findViewById(R.id.et_id);
bt_query= (Button) findViewById(R.id.bt_query);
tv_name= (TextView) findViewById(R.id.tv_name);
//绑定服务
conn = new MyServiceConnection();
bindService(new Intent(this,MyService.class), conn,BIND_AUTO_CREATE);
}
privateclass MyServiceConnection implements ServiceConnection{
//绑定成功
@Override
public void onServiceConnected(ComponentName name, IBinderservice) {
bt_query.setEnabled(true);
//把IBinder对象转化成接口对象
iStudentListener = (IStudentListener) service;
}
@Override
publicvoid onServiceDisconnected(ComponentName name) {
}
}
publicvoid query(View v){
//绑定服务(为什么服务的绑定需要时间)
StringidStr = et_id.getText().toString().trim();
if(TextUtils.isEmpty(idStr)){
Toast.makeText(this,"姐姐 学号不能为空", 0).show();
}else{
intid = Integer.parseInt(idStr);
//调用接口对象的方法(就是调用真实对象的方法)
String name = iStudentListener.queryNameById(id);
tv_name.setText(name);
}
}
@Override
protectedvoid onDestroy() {
super.onDestroy();
unbindService(conn);
}
}
•(掌握)远程服务aidl aidl:android interface definelanguage
安卓接口定义语言。
他是一种新的语言。
这样的语言他可以被编译器自动编译为java语言。
作用:aidl
为了解决进程间通讯,定义了两个应用程序之间的通讯规则。
他和接口非常的相似,我们可以先定义接口,再把接口修改为aidl
.java --> .aidl
aidl语言有自己的语法:
1 它可以识别java里面的基本数据类型
2 它无法识别访问修饰符 public private
3 它无法识别domain
如果要让aidl识别domain
1 class Student implementsParcelable
2 写一个Student.aidl文件
package cn.itcast.domain;
parcelable Student;
aidl 自动生成.java文件后,我们使用什么?
Stub
asInterface(IBinder) IStudent
底层其实走的是代理机制。
aidl 就是一个合同 一式两份
写完aidl之后,把aidl所有的内容带包一起复制到客户端
•(掌握)绑定远程服务 案例
总结
实现
服务器
定义接口 .java 修改为.aidl 删除public修饰符
/**
* 远程的服务(在其他应用程序里面的服务)
*@author apple
*
*/
public class MyService extends Service {
privateString[] names = new String[]{"张学友","刘德华","黎明","郭富城"};
privateMyBinder ibinder = new MyBinder();
@Override
publicIBinder onBind(Intent intent) {
returnibinder;
}
//增强版的IBinder
privateclass MyBinder extends Stub{
@Override
publicString queryNameById(int id) throws RemoteException {
//id只能是1 到4
if(id<= 0 || id > names.length){
return"苍姐姐";
}else{
returnnames[id-1];
}
}
}
}
客户端
从服务器端把aidl文件带包一起复制过来
public class MainActivity extends Activity{
privateEditText et_id;
privateTextView tv_name;
privateMyServiceConnection conn;
privateIStudentListener iStudentListener;
@Override
protectedvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_id= (EditText) findViewById(R.id.et_id);
tv_name= (TextView) findViewById(R.id.tv_name);
//绑定服务
Intentservice = new Intent();
service.setAction("cn.itcast.action.studentquerysystem.server");
conn= new MyServiceConnection();
bindService(service,conn, BIND_AUTO_CREATE);
}
@Override
protectedvoid onDestroy() {
super.onDestroy();
unbindService(conn);
}
privateclass MyServiceConnection implements ServiceConnection{
//绑定的服务是一个 远程的服务 aidl语言 传递过来的对象 :代理对象 代理对象不能直接使用
//需要使用Stub里面的一个方法 asInterface()把代理对象转化成真实对象 再使用
@Override
public void onServiceConnected(ComponentName name,IBinder service) {
//把代理对象转化成真实对象
iStudentListener = Stub.asInterface(service);
}
@Override
publicvoid onServiceDisconnected(ComponentName name) {
}
}
publicvoid query(View v){
StringidStr = et_id.getText().toString().trim();
if(TextUtils.isEmpty(idStr)){
Toast.makeText(this,"姐姐 学号不能为空", 0).show();
}else{
intid = Integer.parseInt(idStr);
//调用接口对象的方法(就是调用真实对象的方法)
try{
Stringname = iStudentListener.queryNameById(id);
tv_name.setText(name);
}catch (RemoteException e) {
e.printStackTrace();
Toast.makeText(this,"服务器端出现了错误",0).show();
}
}
}
}
•(掌握)绑定远程服务(服务返回对象) 实现
服务器:
public classStudent implementsParcelable {
public int id;
public String name;
public int age;
public Student() {
super();
}
public Student(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
@Override
public int describeContents() {
return 0;
}
//把属性写入到Parcel对象
@Override
public void writeToParcel(Parceldest, intflags) {
dest.writeInt(id);
dest.writeString(name);
dest.writeInt(age);
}
public static finalParcelable.Creator<Student> CREATOR = newParcelable.Creator<Student>() {
public StudentcreateFromParcel(Parcel in) {
return new Student(in);
}
public Student[] newArray(int size) {
return new Student[size];
}
};
private Student(Parcel in) {
id = in.readInt();
name = in.readString();
age = in.readInt();
}
}
Student.aidl
IStudent.aidl
•(掌握)服务综合案例-音乐播放器
使用服务来播放音乐。
播放:放歌
暂停:暂停播放 点击暂停按钮:变为继续
停止:停止播放
准备:
1 MainActivity
2MyService
单箭头:方法的调用
双箭头:监听回调
椭圆:状态
public class MainActivity extends Activity{
privateEditText et_path;
privateServiceConnection conn;
privateIMusic iMusic;
@Override
protectedvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_path= (EditText) findViewById(R.id.et_path);
//绑定服务
Intentservice = new Intent(this,MyService.class);
conn= new MyServiceConnection();
bindService(service,conn, BIND_AUTO_CREATE);
}
@Override
protectedvoid onDestroy() {
super.onDestroy();
unbindService(conn);
}
privateclass MyServiceConnection implements ServiceConnection{
@Override
publicvoid onServiceConnected(ComponentName name, IBinder service) {
iMusic= (IMusic) service;
}
@Override
publicvoid onServiceDisconnected(ComponentName name) {
}
}
//播放
publicvoid play(View v){
//获取要播放的歌曲路径
Stringpath = et_path.getText().toString().trim();
if(TextUtils.isEmpty(path)){
Toast.makeText(this,"路径为空",0).show();
}else{
iMusic.play(path);
}
}
//暂停 继续
publicvoid pause(View v){
Buttonbt = (Button) v;
Stringtext = bt.getText().toString();
if("暂停".equals(text)){
iMusic.pause();
bt.setText("继续");
}elseif("继续".equals(text)){
iMusic.moveon();
bt.setText("暂停");
}
}
//停止
publicvoid stop(View v){
iMusic.stop();
}
}
接口的抽取
public interface IMusic {
//播放 path 歌曲的路径
public void play(String path);
//暂停
public void pause();
//继续
public void moveon();
//停止
public void stop();
}
public class MyService extends Service {
privateMyBinder ibinder = new MyBinder();
@Override
publicIBinder onBind(Intent intent) {
returnibinder;
}
privateclass MyBinder extends Binder implements IMusic{
private MediaPlayer mp;
@Override
publicvoid play(String path) {
try{
mp= new MediaPlayer();
mp.reset();//重置
mp.setDataSource(path);//设置播放的资源
mp.prepare();//准备
mp.start();//播放
}catch (Exception e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
publicvoid pause() {
mp.pause();//暂停播放
}
@Override
publicvoid moveon() {
mp.start();//继续
}
@Override
publicvoid stop() {
mp.stop();//停止播放
}
}
}
•(掌握)服务后台音乐播放器界面显示-notification
//用户按下任意的键 该方法都会调用
@Override
publicboolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode== KeyEvent.KEYCODE_BACK){
//按下的就是后退键
//弹出提示框
AlertDialog.Builderbuilder = new AlertDialog.Builder(this);
builder.setTitle("提示信息");
builder.setMessage("是否退出音乐播放器");
builder.setPositiveButton("退出", new OnClickListener() {
@Override
publicvoid onClick(DialogInterface dialog, int which) {
//关闭当前的Activity
finish();
}
});
builder.setNegativeButton("取消", null);
builder.setNeutralButton("隐藏", new OnClickListener() {
@Override
publicvoid onClick(DialogInterface dialog, int which) {
//把当前的MainActivity放置在后台
moveTaskToBack(true);
}
});
AlertDialogdialog = builder.create();
dialog.show();
}
returnsuper.onKeyDown(keyCode, event);
}
•(掌握)服务注册广播接受者 Activity里面注册广播接收者 服务里面注册广播接收者
1 在服务里面写一个class
MyReceiver extendsBroadcastReceiver {
onReceive(){
}
}
2 注册 onCreate() {
registerReceiver(receiver,filter);
}
3 取消注册
onDestory(){
unRegisterReceiver(receiver);
}
public class MyService extends Service {
privateMyReceiver receiver;
@Override
publicvoid onCreate() {
super.onCreate();
receiver= new MyReceiver();
IntentFilterfilter = new IntentFilter();
filter.addAction("");
registerReceiver(receiver,filter);
}
@Override
publicvoid onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
@Override
publicIBinder onBind(Intent intent) {
returnnull;
}
privateclass MyReceiver extends BroadcastReceiver{
@Override
publicvoid onReceive(Context context, Intent intent) {
//执行什么操作
}
}
}
•(掌握)知识点补充 1 服务里面不能直接执行耗时的操作
Service 和 Activity有什么区别:一个有界面 一个没有界面
2 如果要执行耗时的操作,开始子线程(android也提供了一个类IntentService对Service、Thread、Handler线程进行了封装:一般会出现在笔试题中)
3 服务如何和Activity进行通讯:在服务里面发出广播。
activity要和服务进行通信:
1 绑定服务 调用服务里面的方法
2 在Activity里面发送广告给服务里面的广播接收者
服务和Activity进行通讯
1 发送广播
4 如果你希望服务处理完成事情后自动停止,可以在服务里面调用stopSelf();(这样的情况只针对于startService()启动的服务)
面试题 1 请说说intent和intentfilter有什么区别?
intent:意图 是用来串联3大组件:Activity Service BroadcastReceiver
组成:
action 动作
data 数据
category 类别
type 数据的类型
extra 携带的额外参数
component 组件
flag 标记 new_task 在activity的外部启动activity
IntentFilter
java registerReceiver(receiver,filter);
解析清单文件的时候:intent-filter节点
例子:
MainActivity要去激活OtherAcivity
startActivity(new Intent(this,OtherActivity.class));
当你发起激活操作的时候,其实是向操作系统发出了一个指令,操作系统去帮你查找OtherActivity ,如果有就使用ActivityManager把OtherActivity启动,
如果没有找到 报一个notfoundActivityException .
1 该应用里面根本没有OtherActivity
2 OtherActivity没有在清单中配置
例子:
IntentFilter对象是何时被解析?
应用程序安装的时候,android系统会使用Pull解析解析清单文件 并且把数据进行了面向对象的封装。
手机里面是不是会有很多的应用,很多的应用也就是很多的包。很多的应用是很多的用户。很多的应用是很多的进程。
android还设计了一个类来管理所有的应用。
PackageManager
2 aidl: 进程间通讯
java里面是不支持的。
api: IBinder 实现类 Binder java
linux kernel
(内核)驱动
他是android
工程师添加的。进程间通讯。ipc c
代码
作业
用服务来完成的下载器。
Activity和service在两个应用里面。
设计:
1 界面
注意:此图是Activity和Service在同一应用里面的处理方式
下载资源
作者: 袁文博老师 时间: 2015-12-8 08:58
不明觉厉!!!
作者: jzh 时间: 2015-12-9 12:10
好好好好,真不错
作者: mm2015 时间: 2015-12-9 20:10
哥们不错呀。真好
作者: vip003 时间: 2015-12-9 21:10
作者: Xiiian 时间: 2015-12-10 09:26
作者: xk10360108 时间: 2015-12-10 20:07
虽然看不懂,但感觉好厉害的样子,等我学习到能看懂的时候再回来从看一次
作者: Id_820 时间: 2015-12-10 20:13
给力,给力。。。。
作者: 744919632 时间: 2015-12-10 21:40
基哥,更新啊。等着看呢。
作者: 孤独成瘾 时间: 2015-12-10 21:42
不错,虽然看不懂,但很激励人
作者: 邓浩宸 时间: 2015-12-11 12:36
加油黑马黑马
作者: 744919632 时间: 2015-12-11 13:43
加油,基哥最棒。
作者: 小欢 时间: 2015-12-11 16:40
我去,好详细啊,厉害
作者: 梅子派 时间: 2015-12-11 18:46
不明觉厉啊
作者: 梅子派 时间: 2015-12-11 18:47
不明觉厉啊
作者: 梅子派 时间: 2015-12-11 18:49
不明觉厉!!!
作者: 孤独成瘾 时间: 2015-12-11 21:30
厉害啊,赞一个
作者: 啊祥 时间: 2015-12-11 22:45
给力,虽然暂时还看不明白
作者: 林子大了 时间: 2015-12-12 16:24
辛苦
作者: Endless_paradox 时间: 2015-12-12 16:41
马克,收藏
作者: zfl920817 时间: 2015-12-12 23:27
大家好,我是新来的,希望在的朋友加我号,多聊聊
作者: peiyanda 时间: 2015-12-13 22:55
mark一下!
作者: 15225018025 时间: 2015-12-14 07:33
赞一个,支持一下!赞一个,支持一下!赞一个,支持一下!
作者: xiaoxiao2015 时间: 2015-12-14 10:43
作者: not@good@enough 时间: 2015-12-14 19:41
以现在的基础,完全看不懂
作者: 周亚飞 时间: 2015-12-15 08:32
马克,等待进就业班
作者: 水瓶座 时间: 2015-12-15 23:02
赞一下!!!!!!
作者: ToSina 时间: 2015-12-15 23:15
顶顶 顶顶...............
作者: Mr.zhao 时间: 2015-12-16 00:48
要看的明白,估计还有段时间
作者: 乐林荫 时间: 2015-12-16 14:01
非常有用,望持续更新
作者: waihuiquan 时间: 2015-12-16 19:06
好人啊,。好人
作者: “不务正业” 时间: 2015-12-16 21:14
先搞下来。好好准备先。。。顶。。。。
作者: a944090777 时间: 2015-12-17 13:56
zanyige!!!!!
作者: 洪志豪1994 时间: 2015-12-17 20:03
很不错,楼主辛苦了
作者: laiyubin 时间: 2015-12-17 20:53
看都看不懂晕,不明觉厉!
作者: pantianfeng 时间: 2015-12-18 01:22
。。。。。,
作者: schubertw 时间: 2015-12-18 17:54
基哥威武!!!
作者: HMWL 时间: 2015-12-18 22:12
不错 不错 赞一个
作者: labozx 时间: 2015-12-19 00:30
坚持就是胜利,爱拼才会赢!
作者: lxg8136223 时间: 2015-12-19 21:46
我去,厉害
作者: 18338762337 时间: 2015-12-20 18:38
学习中,新技能get
作者: 乐林荫 时间: 2015-12-21 00:06
很牛逼 很有用
作者: labozx 时间: 2015-12-21 00:28
爱拼才会赢!加油赞一个为努力的人。
作者: labozx 时间: 2015-12-21 00:29
爱拼才会赢!加油赞一个为努力的人。
作者: 唐洪超 时间: 2015-12-21 21:20
此处省略几个字,你懂的
作者: 孤独成瘾 时间: 2015-12-21 21:38
哈尔滨是个美丽的城市,有机会一定去
作者: 行走在消逝间 时间: 2015-12-21 22:27
好贴,赞一个
作者: 鳌少宝 时间: 2015-12-21 22:46
加油 加油 努力学习
作者: 18338762337 时间: 2015-12-22 10:49
学习中,顶顶顶
作者: houbofly 时间: 2015-12-22 22:03
赞一个,收藏
作者: tang9137 时间: 2015-12-22 22:34
加油每一天
作者: 18338762337 时间: 2015-12-23 08:33
666666666666
作者: birdy 时间: 2015-12-23 11:23
给力,虽然暂时还看不明白
作者: 韦丹艳58 时间: 2015-12-24 14:07
真心好!很全面
作者: 韦丹艳58 时间: 2015-12-24 14:09
真心全面很有用
作者: 韦丹艳58 时间: 2015-12-24 14:10
真心喜欢
作者: 韦丹艳58 时间: 2015-12-24 16:50
真心有用
作者: YOUTA 时间: 2015-12-24 17:02
好用啊,感谢楼主
作者: WaterTheGreat 时间: 2015-12-24 19:00
学习了!!!!!
作者: duluhuang 时间: 2015-12-24 20:06
666666666666666666666666666
作者: 青菜市场 时间: 2015-12-24 20:19
太厉害了
作者: 程程程程程92 时间: 2015-12-25 13:14
哥们不错
作者: 手有键盘心不慌 时间: 2015-12-25 22:32
十分有用!以后学安卓更方便了
作者: yifuyue 时间: 2015-12-25 23:17
写的真好
作者: 云鱼 时间: 2015-12-26 21:31
就业班的大神么
作者: 王如是 时间: 2015-12-27 00:38
黑马威武
作者: bowllboy 时间: 2015-12-27 15:11
不错的东西
作者: 爱hao者 时间: 2015-12-27 20:19
将来会懂的
作者: zjh742672607 时间: 2015-12-27 20:55
赞一个。
作者: lh951329230 时间: 2015-12-28 09:22
赞赞赞赞赞赞
作者: 谢光智 时间: 2015-12-28 13:06
666666666赞一个!
作者: 小小菜菜 时间: 2015-12-29 01:13
真心得好贴
作者: Accoss-x 时间: 2015-12-29 01:37
加油一起来一起奋斗
作者: peiyanda 时间: 2015-12-29 22:37
顶贴是一种态度!!!
作者: s616622575 时间: 2015-12-29 23:42
好东西多多分享,好人一生平安
作者: bowllboy 时间: 2015-12-30 18:02
虽然只看了标题,但是还是得说谢谢
作者: until 时间: 2015-12-30 22:10
厉害啊 确实厉害 佩服
作者: 笨笨真棒 时间: 2016-1-1 00:35
厉害厉害,多东西
作者: 1050498188 时间: 2016-1-2 00:44
总结的很好
作者: yehua1026 时间: 2016-1-4 19:13
非常好非常好!!!
作者: peiyanda 时间: 2016-1-4 23:04
对于这个,我只想说,先马
作者: li514620797 时间: 2016-1-5 21:31
666666666666666666666666666666
作者: 猜不得先生 时间: 2016-1-6 11:50
666666666666666
作者: 韦丹艳58 时间: 2016-1-6 22:20
牛!!!!!!!!!!!!!!!!!!!!!!!!!!
作者: Smile灬笨笨 时间: 2016-1-7 00:10
4324353621637
作者: pengjk 时间: 2016-1-7 14:04
666666666666
作者: aiheima 时间: 2016-1-9 00:47
不明觉厉啊
作者: 122347 时间: 2016-1-9 10:47
厉害啊,赞一个
作者: qxz394731688 时间: 2016-1-9 15:30
好详细 赞一个
作者: zhou402981948 时间: 2016-1-9 23:03
顶顶顶顶顶顶顶顶顶顶顶顶顶顶
作者: 明日蜕变 时间: 2016-1-11 07:48
顶一个顶一个,赞
作者: Tkight 时间: 2016-1-12 16:57
好大一串代码。。
作者: xiangning 时间: 2016-1-12 23:56
赞 赞 赞
作者: number0kaidi 时间: 2016-1-13 23:44
干货,很受用,谢谢啦
作者: 1066715808 时间: 2016-1-14 08:54
好厉害啊
作者: 苗超维 时间: 2016-1-15 20:33
写的真多啊 ,真全 自己也得努力了
作者: txw126 时间: 2016-1-16 00:15
6666666666666666666
作者: 杨兵1 时间: 2016-1-17 11:11
辛苦了 基哥
作者: black习 时间: 2016-1-17 23:38
厉害啊1111
作者: 阿蛮 时间: 2016-1-18 23:41
现在凡是看到谁的技术分25以上的我就会非常的羡慕!
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |