使用IntentService
服务中的代码都是默认运行在主线程当中的,如果直接在服务里处理一些耗时的逻辑,就会很容易出现ANR的情况。
所以这个时候就需要用到Android多线程编程的技术了,我们应该在服务的每个具体的方法里开启一个子线程,然后在这里去处理那些耗时的逻辑。
一、新建一个MyItentService类继承自IntentService,代码如下
package com.example.yxp.service;
import android.app.IntentService;
import android.content.Intent;
import android.content.Context;
import android.util.Log;
/**
* An {@link IntentService} subclass for handling asynchronous task requests in
* a service on a separate handler thread.
* <p/>
* TODO: Customize class - update intent actions, extra parameters and static
* helper methods.
*/
public class MyIntentService extends IntentService {
public MyIntentService() {
super("MyIntentService");
}
protected void onHandleIntent(Intent intent) {
Log.d("MyIntentService","Thread id is"+ Thread.currentThread().getId());
}
public void onDestroy(){
super.onDestroy();
Log.d("MyIntentService","onDestroy executed");
}
}
二、添加布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<Button
android:id="@+id/start_service"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start Service"/>
<Button
android:id="@+id/stop_service"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Stop Service"/>
<Button
android:id="@+id/bind_service"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Bind Service"/>
<Button
android:id="@+id/unbind_service"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Unbind Service"/>
<Button
android:id="@+id/start_intent_service"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start IntentService"/>
</LinearLayout>
三、修改MyService文件
package com.example.yxp.service;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
private DownloadBinder mBinder = new DownloadBinder();
class DownloadBinder extends Binder {
public void startDownload(){
Log.d("MyService","startDownload executed");
}
public int getProgress(){
Log.d("MyService","getProgress executed");
return 0;
}
}
public IBinder onBind(Intent intent){
return mBinder;
}
public MyService() {
}
public void onCreate(){
super.onCreate();
Log.d("MyService","onCreate executed");
Intent intent = new Intent(this,MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(this,0,intent,0);
Notification notification = new Notification.Builder(this)
.setContentTitle("This is content title")
.setContentText("This is content text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
.setContentIntent(pi)
.build();
startForeground(1,notification);
}
public int onStartCommand(Intent intent,int flags,int startId){
Log.d("MyService","onStartCommand executed");
return super.onStartCommand(intent,flags,startId);
}
public void onDestroy(){
super.onDestroy();
Log.d("MyService", "onDestroy executed");
}
}
四、修改MainActivity文件
package com.example.yxp.service;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import java.sql.BatchUpdateException;
public class MainActivity extends Activity {
private MyService.DownloadBinder downloadBinder;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
downloadBinder = (MyService.DownloadBinder) service;
downloadBinder.startDownload();
downloadBinder.getProgress();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button startService = (Button) findViewById(R.id.start_service);
Button stopService = (Button) findViewById(R.id.stop_service);
startService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent startIntent = new Intent(MainActivity.this,MyService.class);
startService(startIntent);
}
});
stopService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent stopIntent = new Intent(MainActivity.this,MyService.class);
stopService(stopIntent);
}
});
final Button bindService = (Button) findViewById(R.id.bind_service);
final Button unbindService = (Button) findViewById(R.id.unbind_service);
bindService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent bindIntent = new Intent(MainActivity.this,MyService.class);
bindService(bindIntent, connection, BIND_AUTO_CREATE);
}
});
unbindService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
unbindService(connection);
}
});
Button starIntentService = (Button) findViewById(R.id.start_intent_service);
starIntentService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d("MyService", "Thread id is" + Thread.currentThread().getId());
Intent intentService = new Intent(MainActivity.this,MyIntentService.class);
startService(intentService);
}
});
}
}
五、效果