参考书 : 《疯狂Android讲义》
目录
1,问题描述,service线程与UI主线程是同一个线程
2,解决思路,service启动的时候,启动一个线程来处理耗时操作。
3,通过IntentService去启动多线程【Intent服务】
4,前台服务
5,远程服务
《疯狂Android讲义》第10章 Service与BroadcastReceiver 讲的挺好的。建议参考。讲的粗了点,但容易上手。作为初步学习很合适。
1,问题描述,service线程与UI主线程是同一个线程
我们可以通过打印进程ID和线程ID 看到,service 线程与UI主线程是同一个线程。所以service的响应耗时,也会造成UI页面的卡顿。
String.valueOf(android.os.Process.myPid()); // 打印当前的进程ID。
String.valueOf(Thread.currentThread().getId()); //打印线程ID。
2,解决思路,service启动的时候,启动一个线程来处理耗时操作。
在Service服务代码的onstartConmmand启动函数中创建一个继承了Thread的实例对象,并使用start()启动线程
Activity代码:
package com.example.service02;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebView.FindListener;
import android.widget.Button;
public class Main extends Activity {
private Button ButtonNormalService;
private Button ButtonIntentService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service02);
ButtonNormalService = (Button)findViewById(R.id.button1);
ButtonIntentService = (Button)findViewById(R.id.button2);
ButtonNormalService.setOnClickListener(listener);
ButtonIntentService.setOnClickListener(listener);
}
private OnClickListener listener = new OnClickListener() {
@Override
public void onClick(View arg0) {
// 第一种方法: 继承Thread类,标准Java的多线程启动方式。
Intent intent = new Intent(Main.this,Serviceapp.class);
switch (arg0.getId()) {
case R.id.button1:
System.out.println("当前线程为:"+Thread.currentThread().getId());
startService(intent);
break;
case R.id.button2:
stopService(intent);
break;
default:
break;
}
}
};
}
Service服务代码:
package com.example.service02;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class Serviceapp extends Service {
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
// 第一种方法在onstartConmmand启动函数中创建一个继承了Thread的实例对象,并使用start()启动线程
@Override
public int onStartCommand(Intent intent, int flags, int startId) { // 使用一个多线程来处理Service信息 第一种方法
MyThread mythread = new MyThread();
mythread.start();
return super.onStartCommand(intent, flags, startId);
}
private class MyThread extends Thread{ // 在线程的run()中进行处理
@Override
public void run() {
System.out.println("service "+Thread.currentThread().getId());
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
3,通过IntentService去启动多线程【Intent服务】
IntentService是Service类的一个子类,用来处理异步请求,客户端使用IntentService(Intent)方法传递请求给IntentService,IntentService通过work Thread处理每个Intent对象,执行完所有的工作之后,自动停止Service。
Activity代码:
package com.example.service02;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebView.FindListener;
import android.widget.Button;
public class Main extends Activity {
private Button ButtonNormalService;
private Button ButtonIntentService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service02);
ButtonNormalService = (Button)findViewById(R.id.button1);
ButtonIntentService = (Button)findViewById(R.id.button2);
ButtonNormalService.setOnClickListener(listener);
ButtonIntentService.setOnClickListener(listener);
}
private OnClickListener listener = new OnClickListener() {
@Override
public void onClick(View arg0) {
// 第二种方法: 第二种方式使用intentService
Intent intent = new Intent(Main.this,ExampleIntentService.class);
switch (arg0.getId()) {
case R.id.button1:
System.out.println("当前线程为:"+Thread.currentThread().getId());
startService(intent);
break;
case R.id.button2:
stopService(intent);
break;
default:
break;
}
}
};
}
使用Intent
使用IntentService需要两个步骤:
1 必须创造一个无参数的构造方法:将继承的子类名传入到IntentService类中。
2 复写onHandleIntent()方法(处理多线程任务),这个方法是在另外一个线程中的,因此不会阻塞UI,而且这种服务会自动关闭。
package com.example.service02;
import android.app.IntentService;
import android.content.Intent;
public class ExampleIntentService extends IntentService {
public ExampleIntentService() {
super("ExampleIntentService");
// TODO Auto-generated constructor stub
}
@Override
protected void onHandleIntent(Intent arg0) {
System.out.println("service 2222 "+Thread.currentThread().getId());
try
{
Thread.sleep(3000);
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
4,前台服务
服务默认会和UI处于同一个线程,而且不会自动关闭的,除非你调用stopself. 那么如果要执行一个耗时操作,而且希望任务结束的时候服务也自动关闭,
那么你可以尝试IntentService.
5,远程服务
Android服务在默认情况下和它的使用者在同一个应用程序中,更确切的说是在同一个进程中。实际开发中有一种服务,当你想使用的时候会发现它根本
不在当前进程内。例如百度地图就提供一个服务 com.baidu.location.f
远程服务:使用者和服务不在同一个进程。
使用AIDL 实现。