Android service 可以直接更新UI吗
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android service 可以直接更新UI吗相关的知识,希望对你有一定的参考价值。
不可以直接更新UI,但是可以通过几种方式来更新:1 广播。
2 使用binder机制加回调。
3 使用某些系统自带的回调机制,比如数据库监听的回调等等。 参考技术A 参考别的网站:
不可以直接更新UI。
虽然Service也是在主线程工作。但是其无法直接更改ui。
间接的方法有很多的,可以参考android跨进程通信。
activity绑定Service
handler.sentMessage()
handler.post(new Runnable())
BroadcastReceiver
异步通信机制
作者:小小哲
链接:http://www.zhihu.com/question/24109592/answer/88173757
来源:知乎
著作权归作者所有,转载请联系作者获得授权。
Service服务
Android多线程:
定义线程的2种方式:
1、继承Thread类,重写run()方法,new一个实例,用start()方法启动:new MyThread().start();
2、实现Runnable接口:new Thread(new Runnable()){实现run()}
子线程中更新UI:
子线程中不允许更新UI,如果想在子线程中更新UI需要用到异步消息处理机制。
异步消息处理机制:
组成部分:Message:线程之间传递的消息,用于在不同线程之间交换数据。
Handler:用于发送和处理消息。sendMessage()、handleMessage()
MessageQueue:消息队列。存放通过handler发送的消息。每个线程中只有一个MessageQueue
Looper:MessageQueue的管家,调用loop()循环从MessageQueue中取出消息传递到handleMessage()中进行处理。每个线程中只有一个Looper。
步骤:1、主线程中创建一个Handler对象
2、重写handleMessage()方法
3、当子线程中需要进行UI操作时,创建一个Message对象,并通过Handler将消息发送出去。
4、之后消息将会被存放到MessageQueue队列中等待处理,Looper会一直尝试从MessageQueue中取消息,最后分发给handleMessage()。
Handler是主线程创建的,所以handleMessage运行在主线程中,所以可以进行UI操作。
public class MainActivity extends Activity{
public static final int UPDATE_TEXT = 1;
private TextView text;
private Button changeText;
private Handler handler = new Handler();
public void handleMessage(Message msg){
switch(msg.what){
case UPDATE_TEXT:
//进行UI操作
text.setText("Nice to meet you");
break;
default:
break;
}
}
public void onClick(View v){
switch(v.getId){
case R.id.change_text:
new Thread(new Runnable(){
public void run(){
Message message = new Message();
message.what = UPDATE_TEXT;
handler.sendMessage(message);
}
}).start();
break;
default:
break;
}
}
}
AsyncTask(抽象类)
用法:通过创建一个子类继承AsyncTask:class DownloadTask extends AsyncTask<Void,Integer,Boolean>{...},三个参数分别代表:Params(传入的参数),Progress(进度),Result(结果)
方法:onPreExecute():初始化操作
doInBackground(Params...):子线程中运行,处理耗时操作。完成后返回执行结果。调用publicProgress(...)来完成反馈。
onProgressUpdate(Progress...):更新UI
onPostExecute(Result):利用返回数据进行UI操作
Service服务
创建:创建类继承Service,并重写onBind()方法
方法:onCreate()、onStartCommand()、onDestroy()
每一个服务需要在AndroidManifest.xml中注册:<Service android:name=".MyService">
启动和停止服务(借助Intent)
startService(intent对象)、stopService(Intent对象)
stopSelf()在服务中自己停止
活动与服务间的通信
1、新建类继承自Binder类,在其中设置方法
2、创建一个ServiceConnection类,重写onServiceConnected()和onServiceDisconnected()方法,用于活动与服务的绑定和解绑。
3、在onServiceConnected()中调用服务类中相关的public方法
4、通过Intent对象,调用bindService()方法将活动与服务绑定
5、调用unbindService()方法进行解绑。
前台服务(避免被回收)
1 public class MyService extends Service{ 2 ...... 3 public void onCreate(){ 4 super.onCreate(); 5 Notification notification = new Notification(R.drawable.ic_launcher,"Notificationg comes",System.currentTimeMillis()); 6 Intent notificationgIntent = new Intent(this,MainActivity.class); 7 PendingIntent pendingIntent = pendingIntent.getActivity(this,0,notificationIntent,0); 8 notification.setLatestEvnetInfo(this,"This is title","This is content",pendingIntent); 9 startForeground(1,notification); //MyService变成前台服务,并在状态栏中展示出来。 10 } 11 }
IntentService:在服务的具体方法中开启子线程处理耗时操作
1、调用父类构造方法
2、重写onHandleIntent()方法和onDestroy()方法
1 ...... 2 Intent intentService = new Intent(this,MyIntentService.class); 3 startService(intentService); 4 break; 5 ......
定时任务:
Timer类:短期
Alarm机制:可以唤醒cup(推荐)
创建:AlarmManager manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
方法:manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,triggerAtTime,pendingIntent);
以上是关于Android service 可以直接更新UI吗的主要内容,如果未能解决你的问题,请参考以下文章