Server笔记
来源:互联网 发布:梅宏 大数据系统软件 编辑:程序博客网 时间:2024/06/17 18:43
Service笔记
作为Android的四大控件的之一,是每个Android开发者都需要了解的控件,因此特意在这里写下自己的学习笔记。
博客地址 http://blog.csdn.net/sinat_17314503/article/details/53871294
Service是什么,可以干什么
大家都知道Activity是负责前台显示的而Service却恰好相反在后台显示并没有什么界面。例如舞台上的表演,表演者在舞台上表演而幕后工作者,在舞台后面给表演者调灯光、音乐等等。在这里表演者相当于Activity,因为显示在前面观众,观众可以直观的看到,但是幕后工作者观众是看不到的,Service就类似于幕后工作者。既然我们知道Service类似于幕后工作者那么它的能力可以干什么,聪明的你就可以猜出一二分。没错,就是在不阻碍前台的显示的前提下,在后台计算辅助前台更好的显示,还有可以是后台人员发微博,与其他人互动并不一定要一直依附在前台。
Service如何建立和运行
其实Service的建立是十分简单的,只要新建一个类继承Service就好了。
基本上继承以下的方法就可以了
然后在Activity里面点击事件里面写上
Intent i = new Intent(this, EchoService.class);startService(i);
就可以启动了一个后台Service了,但是但是千万不要忘记在注册表里面注册这个Service
<application ...> ... <service android:name=".EchoService"/> </application>
当然又开始就有停止 停止Service的方法
stopService(i);
但是上述的代码并没有运行什么东西。于是我就加一点东西,在后台运行一个计时器,代码如下:
private Timer timer=null; private TimerTask task=null; private int i = 0; public void startTimer(){ if(timer==null){ timer = new Timer(); task = new TimerTask() { @Override public void run() { //--------------------------- //这里注意 现在这个Service没有和前台绑定 //这里可以先注释掉 下面会说Activity和 //Service互动 echoServiceBind.setData(i); i++; if(mDataListener!=null){ mDataListener.Show(i); } //--------------------------- System.out.println(i); } }; timer.schedule(task, 1000,1000); } } public void stopTmer(){ if(timer!=null){ task.cancel(); timer.cancel(); task=null; timer=null; } }
调用的位置
@Overridepublic void onCreate() { startTimer(); Log.e("showme","onCreate"); super.onCreate();}@Overridepublic void onDestroy() { stopTmer(); Log.e("showme","onDestroy"); super.onDestroy();}
运行后你就会发现Logcat在不断打断的打印:
12-25 16:39:33.249 20674-28409/com.example.administrator.servicedemo I/System.out: 112-25 16:39:34.246 20674-28409/com.example.administrator.servicedemo I/System.out: 212-25 16:39:35.247 20674-28409/com.example.administrator.servicedemo I/System.out: 312-25 16:39:36.246 20674-28409/com.example.administrator.servicedemo I/System.out: 412-25 16:39:37.246 20674-28409/com.example.administrator.servicedemo I/System.out: 512-25 16:39:38.246 20674-28409/com.example.administrator.servicedemo I/System.out: 612-25 16:39:39.246 20674-28409/com.example.administrator.servicedemo I/System.out: 712-25 16:39:40.246 20674-28409/com.example.administrator.servicedemo I/System.out: 812-25 16:39:41.246 20674-28409/com.example.administrator.servicedemo I/System.out: 912-25 16:39:42.247 20674-28409/com.example.administrator.servicedemo I/System.out: 10
然后你按home键返回桌面它还是会继续运行,这就是Service。在后台默默的运行。
Service和Activity的交互
到这个时候你会说:这样有卵用啊,Service运行之后和Activity都没有交互。
上面我不是继承了4个方法吗,那么剩下两个就是和Activity的交互有关系的。猜得不错,但是真正有关系的只有
@Overridepublic IBinder onBind(Intent intent) { Log.e("showme","onBind"); return echoServiceBind;}
看它的返回值就知道(IBinder是关于信息底层传递,现在我不懂,不要问我,你只要知道它可以传递数据就可以了)我们需要IBinder对象,现在的状况是 我没有这个对象啊。身为(面向对象的)程序员,当听到没有没有对象那怎么办,那就new啊。没有对象就new一个出来啊。
于是就有下面这个类
public final EchoServiceBind echoServiceBind = new EchoServiceBind();public class EchoServiceBind extends Binder{ private int data = 0; public EchoService getService(){ return EchoService.this; } public int getData() { return data; } public void setData(int data) { this.data = data; }}
然后返回就可以了。
Service那里解决了那么Activity那里怎么办呢。欲知后事如何,且听下会分解。我好想这样说的,越写越多字。
那么我们需要在Activity里面继承ServiceConnection类重写
private EchoService.EchoServiceBind mBind;private EchoService echoService = null; @Override public void onServiceConnected(ComponentName name, IBinder binder) { Log.e("showme","onServiceConnected"); mBind = (EchoService.EchoServiceBind) binder; echoService = ((EchoService.EchoServiceBind) binder).getService(); echoService.addDataListener(new EchoService.DataListener() { @Override public void Show(int t) { Message message = mHandler.obtainMessage(); message.arg1 = t; mHandler.sendMessage(message); } }); } @Override public void onServiceDisconnected(ComponentName name) { Log.e("showme","onServiceDisconnected"); }
通过
echoService = ((EchoService.EchoServiceBind) binder).getService();mBind = (EchoService.EchoServiceBind) binder;
我们可以获取到EchoService
本体 和 EchoService.EchoServiceBind
内部类的本体。
于是我们就可以愉快的调用本体里,但是这里我会告诉你,你都没有绑定,你调用什么。
先说一下这两个方法的作用onServiceConnected
是当Service和Activity绑定成功之后会调用的而onServiceDisconnected
只有在Service发生异常的情况下断掉连接的时候调用。
现在说一下如何绑定Service和Activity。
bindService(i, this, Context.BIND_AUTO_CREATE);
讲完了是不是很快,对就是这么简单就可以绑定Activity和Service。
bindService()方法接收三个参数,第一个参数就是刚刚构建出的Intent对象,第二个参数是前面创建出的ServiceConnection的实例,第三个参数是一个标志位,这里传入BIND_AUTO_CREATE表示在Activity和Service建立关联后自动创建Service。
于是我们可以愉快的调用EchoService本体和EchoServiceBind本体的方法了。
注意
bindService Service中的onCreate()方法得到执行,但onStartCommand()方法不会执行当Startservice和bindService都运行了需要stopService和 unbindService(this);都运行了对应的关闭了Service才停下来。
Service是否可以进行耗时操作
很遗憾的告诉你,不行,因为Service也是运行在UI线程,超过3秒之后就会ANR。那么有什么方法可以让它进行耗时操作,在Service里面开启一个线程进行耗时操作,或者为其开启一个进程
<!--普通的Service转换成远程Service其实非常简单,只需要在注册Service的时候将它的android:process属性指定成:remote就可以--> <!--使用了远程Service后,MyService已经在另外一个进程当中运行了,所以只会阻塞该进程中的主线程,并不会影响到当前的应用程序。--> <service android:name=".MyService2" android:process=":remote"/>
但是有会面临一个问题,卧槽那我怎么和Activity进行交互啊。这就要使用AIDL来进行跨进程通信了(IPC)。
在AS里面步骤
aidl的文件代码如下
package com.example.administrator.servicedemo2;// Declare any non-default types here with import statementsinterface IMyAidlInterface { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString); int plus(int a, int b); String toUpperCase(String str);}
调用
/** * 想和Activity進行交互 这就要使用AIDL来进行跨进程通信了(IPC) * AIDL(Android Interface Definition Language)是Android接口定义语言的意思, * 它可以用于让某个Service与多个应用程序组件之间进行跨进程通信, * 从而可以实现多个应用程序共享同一个Service的功能。 */public class MyService2 extends Service{ public static final String TAG = "MyService"; @Nullable @Override public IBinder onBind(Intent intent) { return mBinder; } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.e(TAG,"onStartCommand() executed"); return super.onStartCommand(intent, flags, startId); } @Override public void onCreate() { super.onCreate(); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } Log.e(TAG,"MyService2 onStartCommand() executed"); Log.e("ThreadID","Service="+Thread.currentThread().getId()); Log.d("TAG", "process id is " + Process.myPid()); } @Override public void onDestroy() { super.onDestroy(); Log.e(TAG,"onDestroy() executed"); } public IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub() { @Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException { } @Override public int plus(int a, int b) throws RemoteException { return a+b; } @Override public String toUpperCase(String str) throws RemoteException { if(str!=null){ return str.toUpperCase(); } return null; } };}
上面的代码做了以下的步骤 一.初始化IMyAidlInterface.Stub
二.将其返回给Activity
Activity调用
private ServiceConnection mConnection2 = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { myBinder2 = IMyAidlInterface.Stub.asInterface(iBinder); try { int a = myBinder2.plus(10,15); String b = myBinder2.toUpperCase("abc"); Toast.makeText(MainActivity.this,b+"顯示一下"+a,Toast.LENGTH_SHORT).show(); } catch (RemoteException e) { e.printStackTrace(); } } // 只有在service因异常而断开连接的时候,这个方法才会用到。 @Override public void onServiceDisconnected(ComponentName componentName) { Log.e("showme","onServiceDisconnected excuted"); } };
上面的代码做了以下的步骤 一.获取IMyAidlInterface.Stub
二.调用里面的方法.
IntentService的使用
原来还有一种方法在Service建线程,我还是太年轻了。在Service里面我们肯定不能直接进行耗时操作,一般都需要去开启子线程去做一些事情,自己去管理Service的生命周期以及子线程并非是个优雅的做法;好在Android给我们提供了一个类,叫做IntentService
使用了IntentService最起码有两个好处,一方面不需要自己去new Thread了;另一方面不需要考虑在什么时候关闭该Service了
使用这个方法我们需要重写
@Overrideprotected void onHandleIntent(Intent intent) {}
在这里面实现你的逻辑然后和Activity的交互可以选择用广播来实现。这个没什么好说的。
参考http://blog.csdn.net/lmj623565791/article/details/47143563
好了需要将的都讲完了。最后 纸上得来终觉浅,绝知此事要躬行
。
参考 http://blog.csdn.net/guolin_blog/article/details/9797169
http://blog.csdn.net/guolin_blog/article/details/11952435
- Server笔记
- 学习sql server笔记。
- CVS-server笔记
- Weblogic Server学习笔记
- SQL Server SP 笔记
- sql server 笔记
- SQL Server学习笔记
- sql server约束笔记
- sql server 笔记
- sql server 笔记
- 关于Server-push(笔记)
- SQL Server超强笔记
- Excel Server 学习笔记
- Sql server 触发器笔记
- SQL笔记 --- SQL Server
- VisualSVN Server配置笔记
- Web Server 笔记
- sql server脚本笔记
- android 面试知识点
- Integer to Roman
- SQL注入的一个简单实例
- Java 遍历Map集合
- AJAX
- Server笔记
- HTML标签marquee
- ajax _two
- 软件工程毕业5年坎坷路途
- spring_guide
- 对所有Activity和Fragment统一添加下拉刷新和上拉加载
- Python找不到模块
- 把源串与密串进行异或,结果就是KEY。
- hadoop安装和维护09--深入理解Linux修改hostname