zoukankan      html  css  js  c++  java
  • 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 @Override
    2     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     @Override
    22     public IBinder onBind(Intent intent) {
    23         System.out.println("Service is binded");
    24         return binder; //返回IBinder实例
    25     }
    26     
    27     @Override
    28     public void onCreate() {
    29         super.onCreate();
    30         System.out.println("Service is Created");
    31         
    32         //新建一 个线程,每隔1秒加1
    33         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     @Override
    48     public boolean onUnbind(Intent intent) {
    49         System.out.print("Service is Unbinded");
    50         return true;
    51     }
    52     
    53     @Override
    54     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     @Override
    109     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     @Override
    117     public boolean onOptionsItemSelected(MenuItem item) {
    118         // Handle action bar item clicks here. The action bar will
    119         // automatically handle clicks on the Home/Up button, so long
    120         // 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 }

    *******************************************************************************************************************************

  • 相关阅读:
    我的ORM之八-- 事件
    JavaScript(四):函数
    JavaScript(三):数据类型转换
    CSS(九):设置盒子水平垂直居中
    CSS(八):定位属性
    CSS(三):引入样式和优先级
    Dapper:安装Dapper时报错
    HTML(四):行级标签和块级标签
    解决Linux里面未启用网卡的问题
    linq操作符:分区操作符
  • 原文地址:https://www.cnblogs.com/rockylearnstodevelop/p/3794311.html
Copyright © 2011-2022 走看看