Androidc学习笔记七之Service服务
来源:互联网 发布:redis 缓存数据库表 编辑:程序博客网 时间:2024/06/10 04:36
android中的Service服务开发和理解
2017/3/13 记载
四大组件之Service服务
服务并不是运行在一个独立的进程当中的,而是依赖于创建服务时所在的应用程序进程中。服务:是实现android中实现程序后台运行的解决方案。它很适合去执行那些不需要在用户交互中长期运行的任务。
并且实际上服务是不会自动开启线程,所有服务代码都是运行在主线程上的,所以我们需要手动创建子线程。
继承:直接实现runable接口或者继承Thread父类(子线程run方法中),启动start()线程。
继承方式:New MyThread().start(); 实现接口方法:new Thread(MyThread).start();
和很多UI库一样。android的UI库也是线程不安全的,所以想要更新应用程序当中的UI元素,
则必须在主线程中进行,否则就会出现异常。
我们写一个小例子看看就知道了
activity_main<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" 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.ldp.com.androidthreadtest.MainActivity"> <Button android:id="@+id/change_text" android:text="Change Text" android:textAllCaps="true" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/text" android:layout_centerInParent="true" android:textSize="20sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" /></RelativeLayout>
MainActivitypackage com.example.ldp.com.androidthreadtest;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.TextView;public class MainActivity extends AppCompatActivity { private TextView text; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); text = (TextView)findViewById(R.id.text); Button button = (Button)findViewById(R.id.change_text); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new Thread(new Runnable() { @Override public void run() { text.setText("Nice to meet you"); } }).start(); } }); }}
效果图:
用android中自带的异步消息处理的使用方法来更新UI就可以解决了
改一下代码:MainActivity
package com.example.ldp.com.androidthreadtest;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.TextView;public class MainActivity extends AppCompatActivity { public static final int UPDATE_TEXT=1; private TextView text; private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what){ //这样就可以实现多个异步消息来实现UI的更新了 case UPDATE_TEXT: text.setText("Nice to meet you"); break; default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); text = (TextView)findViewById(R.id.text); Button button = (Button)findViewById(R.id.change_text); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new Thread(new Runnable() { @Override public void run() { //使用Message对象调用 Message message = new Message(); message.what = UPDATE_TEXT; handler.sendMessage(message); } }).start(); } }); }}
再运行一次就没问题了,可以看到在子线程中并没有执行UI操作,只是创建了一个Message的对象
把这个对象传给handle,然后handleMessage()对它进行处理,这个时候这个方法就是让操作在主线程中运行而不是在子线程。
解析异步消息机制:
它共分四部分:Message、Handle、MessafeQueue、Looper
Message:用于在线程之间传递消息,也可以发送整形数据
handler:处理者,用于发送和处理消息。sendMessage() handleMessage()
MessageQueue:消息队列,在其中存放Handler发送的消息,会一直存在,每一个线程中只会有一个MessageQueue对象
Looper:是每个线程中的MessageQueue的管家,调动loop()方法后就会进入到找消息的无线循环中,找到传给handleMessage()中,每一个线程中只会有一个Looper对象。
效果图:
如果嫌上面的处理步骤很麻烦可以去了解一下android中提供的另外一种工具AsyncTask(基于异步机制的封装)
当然步骤是简单多了。
服务的基本与用法:
直接在项目上就可以新建service服务类,需要去继承service这个类,并实现几个方法
注意:服务是需要在AndroidManifast.xml中注册的
如:新建一个MyService类,在上一个异步消息机制项目上修改
package com.example.ldp.com.androidthreadtest;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.util.Log;public class MyService extends Service { public MyService() { } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } @Override public void onCreate() { super.onCreate(); Log.d("MyService","OnCreat Method Start"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d("MyService","onStartCommand Method Start"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); Log.d("MyService","onDestroy Method Start"); }}
activity_main<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/change_text" android:text="Change Text" android:textAllCaps="false" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/start_service" android:text="Start Service" android:textAllCaps="false" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/stop_service" android:text="Stop Service" android:textAllCaps="false" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/text" android:layout_centerInParent="false" android:textSize="20sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" /></LinearLayout>
MainActivity.javapackage com.example.ldp.com.androidthreadtest;import android.content.Intent;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.TextView;public class MainActivity extends AppCompatActivity implements View.OnClickListener{ public static final int UPDATE_TEXT=1; private TextView text; private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what){ //这样就可以实现多个异步消息来实现UI的更新了 case UPDATE_TEXT: text.setText("Nice to meet you"); break; default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); text = (TextView)findViewById(R.id.text); Button button = (Button)findViewById(R.id.change_text); Button startButton = (Button)findViewById(R.id.start_service); Button stopButton = (Button)findViewById(R.id.stop_service); startButton.setOnClickListener(this); stopButton.setOnClickListener(this); button.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.change_text: new Thread(new Runnable() { @Override public void run() { //使用Message对象调用 Message message = new Message(); message.what = UPDATE_TEXT; handler.sendMessage(message); } }).start(); break; case R.id.start_service: Intent startIntent = new Intent(this,MyService.class); startService(startIntent); break; case R.id.stop_service: Intent stopIntrnt = new Intent(this,MyService.class); stopService(stopIntrnt); break; default: break; } }}
效果图,点击startService发现有oncreat方法和onStartCommand方法执行,多点击几次却只有onStartCommand方法执行
点击停止就执行onDestory方法
效果图:
有没有发现我们是通过活动来通知服务可以执行的。并没有用到活动的作用。
服务的生命周期
效果图:
比如天气软件,当使用的时候会在状态栏显示天气状态,这是前台服务的一种应用方式。
刚刚那个例子当中修改例子:MyService
@Override public void onCreate() { super.onCreate(); Log.d("MyService","OnCreat Method Start"); Intent intent = new Intent(this,MainActivity.class); PendingIntent pi = PendingIntent.getActivity(this,0,intent,0); Notification notification = new NotificationCompat.Builder(this) .setContentTitle("This is content title").setContentText("This is content ") .setWhen(System.currentTimeMillis()).setSmallIcon(R.mipmap.ic_launcher) .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher)) .setContentIntent(pi).build(); startForeground(1,notification); }
效果图:
注意,如果在服务当中发写大量的逻辑代码处理,很有可能导致应用出现ANR(Application Not Response)
所以一个标准的服务,应该写成MyService
@Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d("MyService","onStartCommand Method Start"); new Thread(new Runnable() { @Override public void run() { //具体逻辑实现 stopSelf();//在这里实现停止服务的目的是为了避免一直运行下去,也可以写成stopService() } }).start(); return super.onStartCommand(intent, flags, startId); }
在开始过程中时常会忘记开启线程或者是忘记调用停止服务,导致程序老出问题,所以android中提供了
IntentService父类
package com.example.ldp.com.androidthreadtest;import android.app.IntentService;import android.content.Intent;import android.util.Log;/** * Created by Administrator on 2017/3/13. */public class MyIntentService extends IntentService { public MyIntentService(){ super("MyIntentService");//调用父类的构造函数 } @Override protected void onHandleIntent(Intent intent) { //实现逻辑而不用担心ARN的问题 Log.d("MyIntentService","Thread is "+Thread.currentThread().getId()); } @Override public void onDestroy() { super.onDestroy(); Log.d("MyIntentService","OnDestory Method"); }}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/change_text"
android:text="Change Text"
android:textAllCaps="false"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/start_service"
android:text="Start Service"
android:textAllCaps="false"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/
stop_service" android:text="Stop Service" android:textAllCaps="false" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/myintent_service_start" android:text="Start MyIntent Service" android:textAllCaps="false" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/text" android:layout_centerInParent="false" android:textSize="20sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" /></LinearLayout>
在AndroidManfest.xml中注册服务
<service android:name=".MyService" android:enabled="true" android:exported="true"> </service> <service android:name=".MyIntentService"/>
MyService.java不变
MainActivity.java package com.example.ldp.com.androidthreadtest;import android.content.Intent;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.TextView;public class MainActivity extends AppCompatActivity implements View.OnClickListener{ public static final int UPDATE_TEXT=1; private TextView text; private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what){ //这样就可以实现多个异步消息来实现UI的更新了 case UPDATE_TEXT: text.setText("Nice to meet you"); break; default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); text = (TextView)findViewById(R.id.text); Button button = (Button)findViewById(R.id.change_text); Button startButton = (Button)findViewById(R.id.start_service); Button stopButton = (Button)findViewById(R.id.stop_service); Button myintetnbutton = (Button)findViewById(R.id.myintent_service_start); myintetnbutton.setOnClickListener(this); startButton.setOnClickListener(this); stopButton.setOnClickListener(this); button.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.change_text: new Thread(new Runnable() { @Override public void run() { //使用Message对象调用 Message message = new Message(); message.what = UPDATE_TEXT; handler.sendMessage(message); } }).start(); break; case R.id.start_service: Intent startIntent = new Intent(this,MyService.class); startService(startIntent); break; case R.id.stop_service: Intent stopIntrnt = new Intent(this,MyService.class); stopService(stopIntrnt); break; case R.id.myintent_service_start: Log.d("MainActivity","Thread is "+Thread.currentThread().getId()); Intent intentService = new Intent(this,MyIntentService.class); startService(intentService); break; default: break; } }}
效果图:
做一个集合前面学习的例子:
0 0
- Androidc学习笔记七之Service服务
- Androidc学习笔记一之Activity活动
- Androidc学习笔记六之网络传输
- Androidc参数学习笔记
- Androidc学习笔记四之数据库持久化操作
- Androidc学习笔记八之UI及高级开发技巧
- android学习笔记之十服务(Service)
- android学习笔记之十服务(Service)
- Androidc学习笔记五之四大组件之内容提供器ContentProvider
- Androidc学习笔记二之四大布局及碎片理解用法
- Androidc学习笔记三之BroadcastReceiver广播接收器及单双页模式
- Androidc学习笔记九之Alarm机制、Dom模式、APK签名
- Android 学习笔记之——服务(service)
- Android四大组件之Service服务学习笔记(一)
- android service 服务学习笔记
- Android学习之服务Service
- Service学习之--------绑定服务
- 学习笔记之Service
- python爬虫之图片
- C语言天梯赛储备函数
- Bzoj 3172: [Tjoi2013]单词(fail树)
- Introduction to 3D Game Programming with DirectX 11学习笔记 6 Direct3D中的绘制(三)像素着色器
- 最大连续子数组
- Androidc学习笔记七之Service服务
- 关于Ajax
- Android 跳转到系统联系人获取姓名和手机号
- Maven多模块项目
- md5加密
- Cookie 和 LocalStorage 比较
- Linux命令
- Libnids--函数调用顺序之nids_init()
- c++编译错误:invalid new-expression of abstract class type