深入四大组件之Service
来源:互联网 发布:淘宝店铺pc端首页多高 编辑:程序博客网 时间:2024/06/05 23:15
之前学习android的时候,说实话自己并没有特别认真学习Service。以至于等自己用到的时候一头雾水,“书到用时方恨少”这话一点也不假呀。为了多读书,所以就下定决心,好好的把Service深入的了解一下。
我划分了几个学习步骤,由简单认识到深入了解。我们给出官方API Service官方API
一:Service的概念特性
(1)概念 :Service是后台运行的没有界面的优先级高于Activity的一个组件。
(2)Service与Thread的区别:
Service和Thread之间没有任何关系!
之所以有不少人会把它们联系起来,主要就是因为Service的后台概念。Thread我们大家都知道,是用于开启一个子线程,在这里去执行一些耗时操作就不会阻塞主线程的运行。而Service我们最初理解的时候,总会觉得它是用来处理一些后台任务的,一些比较耗时的操作也可以放在这里运行,这就会让人产生混淆了。但是,如果我告诉你Service其实是运行在主线程里的,你还会觉得它和Thread有什么关系吗?
其实,后台和子线程是两个完全不同的概念:
Android的后台就是指,它的运行是完全不依赖UI的。即使Activity被销毁,或者程序被关闭,只要进程还在,Service就可以继续运行。比如说一些应用程序,始终需要与服务器之间始终保持着心跳连接,就可以使用Service来实现。你可能又会问,Service既然是运行在主线程里,在这里一直执行着心跳连接,难道就不会阻塞主线程的运行吗?当然会,但是我们可以在Service中再创建一个子线程,然后在这里去处理耗时逻辑就没问题了。
既然在Service里也要创建一个子线程,那为什么不直接在Activity里创建呢?这是因为Activity很难对Thread进行控制,当Activity被销毁之后,就没有任何其它的办法可以再重新获取到之前创建的子线程的实例;而且在一个Activity中创建的子线程,另一个Activity无法对其进行操作。但是Service就不同了,所有的Activity都可以与Service进行关联,然后可以很方便地操作其中的方法,即使Activity被销毁了,之后只要重新与Service建立关联,就又能够获取到原有的Service中Binder的实例。因此,使用Service来处理后台任务,Activity就可以放心地finish,完全不需要担心无法对后台任务进行控制的情况。
(3)注意项
(4)服务的类型
二:Service的生命周期以及两种启动方式
1、使用start方式启动服务
package com.example.servicedemo;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.util.Log;public class MyStartService extends Service {@Overridepublic void onCreate() {// TODO Auto-generated method stubLog.i("info", "Service--onCreate()");super.onCreate();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// TODO Auto-generated method stubLog.i("info", "Service--onStartCommand()");return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {// TODO Auto-generated method stubLog.i("info", "Service--onDestroy()");super.onDestroy();}@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubLog.i("info", "Service--onBind()");return null;}}(2)在我们的MainActivity中修改布局文件
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Start:" /> <Button android:id="@+id/start" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="doClick" android:text="StartService" /> <Button android:id="@+id/stop" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="doClick" android:text="StopService" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Bind:" /> <Button android:id="@+id/bind" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="doClick" android:text="BindService" /> <Button android:id="@+id/play" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="doClick" android:text="播放" /> <Button android:id="@+id/pause" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="doClick" android:text="暂停" /> <Button android:id="@+id/next" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="doClick" android:text="下一首" /> <Button android:id="@+id/pervious" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="doClick" android:text="上一首" /> <Button android:id="@+id/unbind" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="doClick" android:text="UnBindService" /></LinearLayout>效果图为:
intent1 = new Intent(MainActivity.this, MyStartService.class);startService(intent1);上面的为启动的方式,当我们停止的时候直接一句话就可以了。点击stopService按钮
stopService(intent1);运行结果是什么呢?
2、使用bind方式启动服务
package com.example.servicedemo;import android.app.Service;import android.content.Intent;import android.content.ServiceConnection;import android.os.Binder;import android.os.IBinder;import android.util.Log;public class MyBindService extends Service{@Overridepublic void onCreate() {// TODO Auto-generated method stubLog.i("info", "BindService--onCreate()");super.onCreate();}public class MyBinder extends Binder{public MyBindService getService(){return MyBindService.this;}}@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubLog.i("info", "BindService--onBind()");return new MyBinder();}@Overridepublic void unbindService(ServiceConnection conn) {// TODO Auto-generated method stubLog.i("info", "BindService--unbindService()");super.unbindService(conn);}@Overridepublic void onDestroy() {// TODO Auto-generated method stubLog.i("info", "BindService--onDestroy()");super.onDestroy();}public void Play(){Log.i("info", "播放");}public void Pause(){Log.i("info", "暂停");}public void Pervious(){Log.i("info", "上一首");}public void next(){Log.i("info", "下一首");}}(2)MyBindService类中的方法说明。
(3)在MainActivity启动我们服务,点击BindService按钮
intent2 = new Intent(MainActivity.this, MyBindService.class);bindService(intent2, conn, Service.BIND_AUTO_CREATE);我们看与start方式启动有一些稍微的区别,就是bindService(intent2,conn,Service.BIND_AUTO_CREATE);
ServiceConnection conn = new ServiceConnection() {@Override//当服务跟启动源断开的时候 会自动回调public void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stub}@Override//当服务跟启动源连接的时候 会自动回调public void onServiceConnected(ComponentName name, IBinder binder) {// TODO Auto-generated method stubservice = ((MyBinder)binder).getService();}};看注释应该就应该能明白。
package com.example.servicedemo;import com.example.servicedemo.MyBindService.MyBinder;import android.app.Activity;import android.app.Service;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.view.Menu;import android.view.View;public class MainActivity extends Activity {Intent intent1;Intent intent2;MyBindService service;ServiceConnection conn = new ServiceConnection() {@Override//当服务跟启动源断开的时候 会自动回调public void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stub}@Override//当服务跟启动源连接的时候 会自动回调public void onServiceConnected(ComponentName name, IBinder binder) {// TODO Auto-generated method stubservice = ((MyBinder)binder).getService();}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);}public void doClick(View v){switch (v.getId()) {case R.id.start: intent1 = new Intent(MainActivity.this, MyStartService.class);startService(intent1);break;case R.id.stop:stopService(intent1);break;case R.id.play:service.Play();break;case R.id.pause:service.Pause();break;case R.id.pervious:service.Pervious();break;case R.id.next:service.next();break;case R.id.bind:intent2 = new Intent(MainActivity.this, MyBindService.class);startService(intent2);bindService(intent2, conn, Service.BIND_AUTO_CREATE);break;case R.id.unbind:unbindService(conn);break;}}@Overrideprotected void onDestroy() {// TODO Auto-generated method stubstopService(intent2);unbindService(conn);super.onDestroy();}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}}真开心呀,写了一个小时终于写完一部分了。到此为止我们的Service基本用法算是完了。接下来就是更高级的了。我们写这篇博客的目的,也主要是为了学习下面的高级进阶。上面的主要是铺垫而已。
三、系统服务
常用系统服务:后台Service在系统启动时被SystemServer开启:1.MountService:监听是否有SD卡安装及移除2.ClipboardService:提供剪切板功能3.PackageManagerService:提供软件包的安装移除及查看4.电量,网络连接状态等等使用的时候通过getSystemService()的方法来实现:这是一个Activity的一个方法,通过传入name->object>服务对象WINDOW_SERVICE -- WindowManager -- 管理打开的窗口程序LAYOUT_INFLATER_SERVICE -- LayoutInflater -- 取得XML里定义的ViewACTIVITY_SERVICE -- ActivityManager -- 管理应用程序的系统状态POWER_SERVICE -- PowerManger -- 电源服务ALARM_SERVICE -- AlarmManager -- 闹钟服务NOTIFICATION_SERVICE -- NotificationManager -- 状态栏服务KEYGUARD_SERVICE -- KeyguardManager -- 键盘锁服务LOCATION_SERVICE -- LocationManager -- 位置服务,如GPSSEARCH_SERVICE -- SearchManager -- 搜索服务VEBRATOR_SERVICE -- Vebrator -- 手机震动服务CONNECTIVITY_SERVICE -- Connectivity -- 网络连接服务WIFI_SERVICE -- WifiManager -- Wi-Fi服务TELEPHONY_SERVICE -- TelephonyManager -- 电话服务下面我们用代码演示一下如何使用这些服务。
LayoutInflater inflater = (LayoutInflater) MainActivity.this.getSystemService(LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.activity_main, null); setContentView(view);
这个方法在平时我们的开发当中是非常有必要的。因为我们可以通过LayoutInflater动态的加载我们布局。
2、判断网络的连接状态判断网络是否连接public boolean isNetworkConnected(Context context) { // 判断网络的方法 if (context != null) { ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();// 获取网络连接状态信息 if (mNetworkInfo != null) {// 如果不为空 return mNetworkInfo.isAvailable();// 返回网络状态属于活动状态 } } return false; }
<uses-permission android:name="android.permission.SEND_SMS"></uses-permission><uses-permission android:name="android.permission.READ_SMS"></uses-permission><uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
String phone = phoneEt.getText().toString(); String context = contextEt.getText().toString(); SmsManager manager = SmsManager.getDefault(); ArrayList<String> list = manager.divideMessage(context); //因为一条短信有字数限制,因此要将长短信拆分 for(String text:list){ manager.sendTextMessage(phone, null, text, null, null); } Toast.makeText(getApplicationContext(), "发送完毕", Toast.LENGTH_SHORT).show();
/** * 调起系统发短信功能 * @param phoneNumber * @param message */public void doSendSMSTo(String phoneNumber,String message){if(PhoneNumberUtils.isGlobalPhoneNumber(phoneNumber)){Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:"+phoneNumber)); intent.putExtra("sms_body", message); startActivity(intent);}}还有其他好多种短信发送的。我们给出一个链接。自己可以看看写的非常详细几种常见的发送短信方式
四、在Service里的耗时操作
package com.example.servicetest;import android.app.Service;import android.content.Intent;import android.os.IBinder;public class MyService extends Service { public static final String TAG = "MyService"; //服务执行的操作 @Override public int onStartCommand(Intent intent, int flags, int startId) { new Thread(new Runnable() { public void run() { //处理具体的逻辑 stopSelf(); //服务执行完毕后自动停止 } }).start(); return super.onStartCommand(intent, flags, startId); } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } }我在onStartCommand里面定义了一个子线程。当然在子线程处理完服务之后stopSelf自动停止服务。这是我们自然而然想到的办法,但是这种办法也有不妥,因为有时候我们老是忘记启动线程或者是停止服务。怎么办呢?谷歌给我们提供了一种方法,那就是IntentService类 。它可以为我们异步的创建服务,还可以自动的停止服务。是不是很高大上。好,接下来好好地认识一下他,如何去用。
IntentService的工作机制
package com.example.servicetest;import android.app.IntentService;import android.content.Intent;import android.util.Log;public class MyIntentService extends IntentService{ public MyIntentService() { super("MyIntentService");//调用父类有参构造函数。这里我们手动给服务起个名字为:MyIntentService // TODO Auto-generated constructor stub } //该方法在会在一个单独的线程中执行,来完成工作任务。任务结束后,该Service自动停止 @Override protected void onHandleIntent(Intent intent) { // TODO Auto-generated method stub for(int i = 0;i<3;i++) { //打印当前线程的id Log.d("MyIntentService","IntentService线程的id是:"+Thread.currentThread().getId()); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Log.d("MyIntentService","onDestroy"); }}上面这段我们可以看到,我们需要继承IntentService,以前我们都是直接继承Service。然后在onHandlerIntent重写方法当中执行耗时操作。在我们这个例子里面我们只是每过一秒就在后台打印当前的线程ID。我们还是一样在我们的MainActivity中启动Service。我们使用Start方式启动就行。代码和上面的一样,就不给出了。
- 深入四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- WebRTC VideoEngine综合应用示例(二)——集成OPENH264编解码器
- Kruskal算法
- 下载链接后的MD5是什么意思?
- iOS 随机图片验证码
- WebRTC VideoEngine综合应用示例(三)——集成X264编码和ffmpeg解码
- 深入四大组件之Service
- [Notes] 摘《何林--信息学中的守恒法》
- 点击其他地方隐藏div
- celebrate Google developer
- Java -- 入口函数浅析
- java线程中yield(),sleep(),wait()区别详解
- SAP ABAP自建表被删,如何查看记录
- opnet之事件列表
- Textview 设置字时,如果字数很多让text 自动换行