首页 > 代码库 > Service & Timer & Handler & leaked ServiceConnection
Service & Timer & Handler & leaked ServiceConnection
定义一个Service,每隔一秒钟,变量count增加1;
在Activity里bindService,然后利用new Timer() 和 Handler,每隔一秒利用IBinder实例mBinder的getNumber()方法读取count的最新值,并显示在TextView.
首次运行,报错。
Debug模式,发现MainActivity.class 79行的HandleMessage()方法在onServiceConnected()(MainActivity.class 第68行)之前就执行了,mBinder对象还未初始化(该对像是回调onServiceConnected()方法时初始化 ), 所以才会出现NullPointerException.
试着去解决问题:在83行增加判断语句
83 if (mBinder != null) { //**此处未加if判断语句就会出错,提示NullPointerException 84 // 获取Service中的实时Count值,并在UI中显示 85 mCount = mBinder.getNumber() + ""; 86 }
87 88 // 在Toast中显示count 89 textView1.setText(mCount);
然后在程序可以运行,但是刚开始TextView显示“default”(mCount的初始值) , 一秒钟之后才开始显示累加的数字。
但是LogCat还是有抱错
问题1:为什么HandleMessage()方法在onServiceConnected()之前就执行了?
问题2:为什么有ServiceConnection 泄漏?
问题2的已解决:在MainActivity中,改写onDestroy()
1 @Override2 protected void onDestroy() {3 super.onDestroy();4 //在关闭Activity时取消与mService的绑定5 unbindService(conn); 6 }
*******************************************************************************************************************************
Service定义如下:
1 package com.rocky.myfirstserviceapp.service; 2 3 import android.app.Service; 4 import android.content.Intent; 5 import android.os.Binder; 6 import android.os.IBinder; 7 8 public class MyService extends Service { 9 10 private int count = 0;11 private boolean quit = false;12 private MyBinder binder = new MyBinder();13 14 public class MyBinder extends Binder{15 public int getNumber(){16 //获取即时数值17 return count;18 }19 }20 21 @Override22 public IBinder onBind(Intent intent) {23 System.out.println("Service is binded");24 return binder; //返回IBinder实例25 }26 27 @Override28 public void onCreate() {29 super.onCreate();30 System.out.println("Service is Created");31 32 //新建一 个线程,每隔1秒加133 new Thread(){34 public void run() {35 while(!false){36 try {37 Thread.sleep(1000);38 } catch (InterruptedException e) {39 e.printStackTrace();40 }41 count++;42 }43 };44 }.start();45 }46 47 @Override48 public boolean onUnbind(Intent intent) {49 System.out.print("Service is Unbinded");50 return true;51 }52 53 @Override54 public void onDestroy() {55 super.onDestroy();56 this.quit = true;57 System.out.print("Service is destroyed");58 }59 60 }
*******************************************************************************************************************************
Activity 定义如下:
1 package com.rocky.myfirstserviceapp; 2 3 import java.util.Timer; 4 import java.util.TimerTask; 5 6 import com.rocky.myfirstserviceapp.service.MyService; 7 import com.rocky.myfirstserviceapp.service.MyService.MyBinder; 8 9 import android.app.Activity; 10 import android.app.ActionBar; 11 import android.app.Fragment; 12 import android.app.Service; 13 import android.content.ComponentName; 14 import android.content.Intent; 15 import android.content.ServiceConnection; 16 import android.os.Bundle; 17 import android.os.Handler; 18 import android.os.IBinder; 19 import android.os.Message; 20 import android.view.LayoutInflater; 21 import android.view.Menu; 22 import android.view.MenuItem; 23 import android.view.View; 24 import android.view.ViewGroup; 25 import android.widget.TextView; 26 import android.widget.Toast; 27 import android.os.Build; 28 29 /** 30 * 31 * @author LinXing 利后Service从1增加到100, 每秒加1。 多个Activity从Service中提取即时数值 32 */ 33 34 public class MainActivity extends Activity { 35 36 // 保存所启动的Service的IBinder对象 37 private MyService.MyBinder mBinder; 38 private TextView textView1; 39 40 private ServiceConnection conn; 41 42 // 接收信息后更新UI 43 private Handler mHandler; 44 45 private String mCount = "default"; 46 47 @Override 48 protected void onCreate(Bundle savedInstanceState) { 49 super.onCreate(savedInstanceState); 50 setContentView(R.layout.activity_main); 51 52 textView1 = (TextView) findViewById(R.id.textView1); 53 54 // 创建启动Service的Intent 55 Intent intent = new Intent(this, MyService.class); 56 57 58 // 定义一个ServiceConnection对象 59 conn = new ServiceConnection() { 60 61 @Override 62 public void onServiceDisconnected(ComponentName name) { 63 System.out.print("Service is disconnected"); 64 } 65 66 @Override 67 public void onServiceConnected(ComponentName name, IBinder service) { 68 mBinder = (MyService.MyBinder) service; 69 System.out.print("Service is connected"); 70 } 71 }; 72 73 // 绑定service 74 bindService(intent, conn, Service.BIND_AUTO_CREATE); 75 76 // 实现Handler 77 mHandler = new Handler() { 78 @Override 79 public void handleMessage(Message msg) { 80 super.handleMessage(msg); 81 82 if (msg.what == 0x33) { 83 if (mBinder != null) { //**此处未加if判断语句就会出错,提示NullPointerException 84 // 获取Service中的实时Count值,并在UI中显示 85 mCount = mBinder.getNumber() + ""; 86 } 87 88 // 在Toast中显示count 89 textView1.setText(mCount); 90 } 91 92 } 93 }; 94 95 // 计时器,每隔一秒发送一个消息 96 new Timer().schedule(new TimerTask() { 97 98 @Override 99 public void run() {100 Message msg = new Message();101 msg.what = 0x33;102 mHandler.sendMessage(msg);103 }104 }, 0, 1000);105 106 }107 108 @Override109 public boolean onCreateOptionsMenu(Menu menu) {110 111 // Inflate the menu; this adds items to the action bar if it is present.112 getMenuInflater().inflate(R.menu.main, menu);113 return true;114 }115 116 @Override117 public boolean onOptionsItemSelected(MenuItem item) {118 // Handle action bar item clicks here. The action bar will119 // automatically handle clicks on the Home/Up button, so long120 // as you specify a parent activity in AndroidManifest.xml.121 int id = item.getItemId();122 if (id == R.id.action_settings) {123 return true;124 }125 return super.onOptionsItemSelected(item);126 }127 128 }
*******************************************************************************************************************************