Android Handler leak分析及解决办法详解

 更新时间:2017年7月6日 23:23  点击:2052
小编给大家推荐的这篇文章详细解析了Android Handler leak分析及解决办法,非常有用,有兴趣的同学可以参考一下

Android Handler leak 分析及解决办法

 In Android, Handler classes should be static or leaks might occur,  Messages enqueued on the application thread's MessageQueue also retain  their target Handler. If the Handler is an inner class, its outer class  will be retained as well. To avoid leaking the outer class, declare the  Handler as a static nested class with a WeakReference to its outer  class.

     在Android中,Handler类应该是静态的,否则,可能发生泄漏。在应用程序线程的MessageQueue中排队的Message对象  还保留他们的目标Handler。如果Handler是一个内部类(注:无论是匿名还是非匿名,匿名是比较常见用法),它的外部类将被保留(至于为什么, 请参考Java嵌套类相关说明)。为了避免泄漏外部类,声明一个Handler子类为静态内部类(注:这样就避免了Handler对象对外部类实例的自动引用),其内部持有一个对外部类对象的WeakReference。

    上面是HandlerLeak的详细解释,同时下划线部分也提供了解决方案的思路。我们需要再分析一下几个泄漏问题:(1)  排队中的Message对象对Handler的持有导致泄漏;(2)Handler对象对外部类(如Activity或Service)实例的强引用持  有。是由于这两个原因同时作用导致出现泄漏的可能。我们的解决方案可以从原因出发,清除这两个原因,就会比较完整的解决这个问题。

    方案:(1)针对第1个原因,在使用Handler的组件生命周期结束前清除掉MessageQueue中的发送给Handler的Message对象(例如在Activity或Service的onDestroy()中调用Handler的remove*方法);(2)针对第2个原因,Handler的实现类采用静态内部类的方式,避免对外部类的强引用,在其内部声明一个WeakReference引用到外部类的实例。

    关于Handler的remove*方法,这儿介绍一下(可以参考源码或文档)

removeCallbacks(Runnable r) ——清除r匹配上的Message。

removeCallbacks(Runnable r, Object token) ——清除r匹配且匹配token(Message.obj)的Message,token为空时,只匹配r。

removeCallbacksAndMessages(Object token) ——清除token匹配上的Message。

removeMessages(int what) ——按what来匹配

removeMessages(int what, Object object) ——按what来匹配

我们更多需要的是清除以该Handler为target的所有Message(包括Callback),那么调用如下方法即可

    handler.removeCallbacksAndMessages(null);

    最终代码像下面这样

 

 代码如下 复制代码

packageorg.dragonboy.example;

  

importjava.lang.ref.WeakReference;

  

importandroid.app.Activity;

importandroid.os.Bundle;

importandroid.os.Handler;

importandroid.os.Message;

  

/**

 * @author dragonboyorg@qq.com

 */

publicclassMyActivityextendsActivity {

  privateMyHandler mHandler;

  

  @Override

  protectedvoidonCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

  

    mHandler =newMyHandler(this);

  }

  

  @Override

  protectedvoidonDestroy() {

    // Remove all Runnable and Message.

    mHandler.removeCallbacksAndMessages(null);

  

    super.onDestroy();

  }

  

  staticclassMyHandlerextendsHandler {

    // WeakReference to the outer class's instance.

    privateWeakReference<myactivity> mOuter;

  

    publicMyHandler(MyActivity activity) {

      mOuter =newWeakReference<myactivity>(activity);

    }

  

    @Override

    publicvoidhandleMessage(Message msg) {

      MyActivity outer = mOuter.get();

      if(outer !=null) {

        // Do something with outer as your wish.

      }

    }

  }

}

</myactivity></myactivity>

 

小编推荐的这篇文章介绍了JS实现直接运行html代码的方法,非常实用,有兴趣的同学快来看看吧

1、实例代码:

 

 代码如下 复制代码

<!DOCTYPE html>

<html>

  <head>

    <meta charset='utf-8'/>

    <title>直接运行 html 代码</title>

  </head>

  <body>

    <textarea style='width:300px;height:200px;'id='txtCode'></textarea><br/>

    <input type='button'value='直接运行'id='btnRun'/>

    <script>

      document.getElementById('btnRun').onclick =function(){

        varrunHtml = document.getElementById('txtCode').value;

        if(runHtml){

          varwin = window.open('','运行窗口');

          win.document.open();

          win.document.write(runHtml);

          win.document.close();

        }

        else{

          alert('请输入!');

        }

      }

    </script>

  </body>

</html>

 

2、运行效果图如下:

本文介绍了jsonp跨域请求实现示例,非常有用,不会的同学可以看看

网上看了很多关于jsonp的资料,发现在本机运行后实现不了,有的是有错漏,有的是说的比较含糊,接合自己的情况,整了一个可运行的示例;

前言:

ajax请求地址:http://192.168.1.102:8080/carop/jsonp

服务端要返回的jsonp字符串:jsonpCallback({"name":"刘德华","电话":"17688888888"})

jsonp写法,写法上可以理解成一个javascript函数的执行,例如alert("hello world")会弹出hello  world的窗口,再例如alert({"name":"刘德华"})会弹出[object  Object]的窗口。(注意这里参数两端没加双引号,它是一个有属性的对象而不是一个字符串)

那么本示例的jsonp中,可以将jsonpCallback理解成函数名,{"name":"刘德华","电话":"17688888888"}这个对象是这个函数执行时所要传递的参数。

客户端

 

 代码如下复制代码

$.ajax({

       type:"get",

       async:false,

url:"http://192.168.1.102:8080/carop/jsonp",

       dataType:"jsonp",

jsonpCallback:"jsonpCallback",      

       success:function(data){

       alert(data.name+"\n "+data.tel);

       }

     });

 

其他的ajax方法比如getjson亦可,写法上有区别,这里仅采用一种方法。

说明:jsonpCallback:"jsonpCallback",前一个ajax参数表示要执行的函数,后面的”jsonpCallback“,这个是服务器返回jsonp的javascript函数名。(网上有相关资料这个参数写的是jsonp而不是jsonpCallback,经实际测试要写成jsonpCallback,jquery版本1.8,所测试浏览器为火狐和edge)

服务端

servlet控制器层直接返回jsonp;

 

 代码如下复制代码

importjava.io.IOException;

importjava.io.PrintWriter;

importjavax.servlet.ServletException;

importjavax.servlet.annotation.WebServlet;

importjavax.servlet.http.HttpServlet;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

@WebServlet("/jsonp")

publicclassjsonpextendsHttpServlet{

@Override

protectedvoiddoGet(HttpServletRequest req, HttpServletResponse resp)

 throwsServletException, IOException {

 resp.setCharacterEncoding("UTF-8");

 //System.out.println("进入jsonp");

 resp.setContentType("text/json;charset=utf-8");

 String json="{\"name\":\"刘德华\",\"tel\":\"17688888888\"}";

 String jsonp="jsonpCallback("+json+")";

 PrintWriter pw=resp.getWriter();

 System.out.println(jsonp);

 pw.print(jsonp);

}

@Override

 protectedvoiddoPost(HttpServletRequest req, HttpServletResponse resp)

  throwsServletException, IOException {

 // TODO Auto-generated method stub

 doGet(req, resp);

 }

}

 

本篇文章主要为大家介绍了手机网站开发场景应用的设计方法,很有参考价值,有兴趣的小伙伴就来看一看吧。

移动数据终端由于和用户形影不离,进而几乎成为用户身体的一部分,对其依赖性的深入性不言而喻,所以,移动终端在诞生时就已经携带了天然优势,这使手机网站的设计师,得以获得新的大展身手的天地。

第一、移动端设计效果难以判断

虽然移动端场景的设计应用空间非常广阔,但是终端场景设计的效果,却由于空间的阻隔,设计师无法看到现场的实际效果,在这样的状况之下,要想获得现实场景当中,用户在使用设计师设计的手机网站应用场景时所获得的真实感受以及碰到的难题和槽点,就必须依赖于手机网站场景设计的模拟机制了。

第二、以案例说明场景设计模拟的重要性

如果以使用者最常见到的订购观影服务这一系列的应用为例来介绍,我们首先可以按照研究的方便把这个应用的过程按先后顺序分成六个步骤,在线买票、到达电影院,从售票终端取票,通过自动检票机,消费过程,以及通过观影论坛发布评论。根据这些步骤,某手机软件在每一个功能段都嵌入了一些功能,如果票已经订购成功,那么手机网站页面就会出现一个人型图案,这个人型图案会在不同的阶段变换功能,比如在检票的时候可以变成验证码,而在出门要去电影院的时候可以与叫车软件相连接。

第三、根据使用场景来设计应用的思路与方法

设计师融入应用场景,是很重要的一种换位思维,不过能够体会到用户的需求只是基于场景应用开发的最前端,在这之后还要经过四个步骤的考验才能将一个应用打造得初见雏形,这四个步骤分别是场景描述,需求点挖掘,服务思路策划和效果审核。

其中尤以服务思路策划最为重要,因为对手机网站上这款应用最核心的智慧都凝聚在这个步骤里,而且即便是对于后期的代码编写等繁杂操作,所能获得的效果本质上也是受这个解决问题思路的优劣左右的。

来源易百讯网站建设http://www.yibaixun.com/news/1451.html 原文地址,欢迎分享 转载请注明出处。

[!--infotagslink--]

相关文章

  • PHP session_start()很慢问题分析与解决办法

    本文章来给各位同学介绍一下关于PHP session_start()很慢问题分析与解决办法,希望碰到此问题的同学可进入参考。 最近在做东西的时候发现一个问题 有一个接口挂...2016-11-25
  • php中json_decode()和json_encode()用法与中文不显示解决办法

    本文章介绍了关于php中json_decode()和json_encode()用法与中文不显示解决办法,有需要的朋友可以参考一下下。 php中json_decode()和json_encode() 1.json_decode(...2016-11-25
  • phpexcel导出数据身份证后四位0000解决办法

    在php中我们如果要导入excel数据我们通常会使用phpexcel插件了,但是有朋友会发与使用phpexcel导出数据出现身份证后四位是0000情况了,下面我们就来看解决办法。 最...2016-11-25
  • 401错误码代表什么 401错误解决办法

    401是HTTP状态码的一种,属于“请示错误”,表示请求可能出错,已妨碍了服务器对请求的处理。具体的401错误是指:未授权,请求要求进行身份验证。登录后,服务器可能会返回对页面...2017-01-22
  • apache网站提示503错误解决办法

    Apache status 503 的原因大致有如下几种情况 : 1、 CPU 负载过高,服务器响应不过来,返回503 2、 系统连接数超限,超过MaxVhostClients的上限,返回503 3、 单IP连接数超限,超过M...2016-01-28
  • Perl CPAN::Modulelist的解决办法

    今天用CPAN安装Term::ReadLine,报了个这样的错误 Going to read /root/.cpan/sources/modules/03modlist.data.gz Can't locate object method "data" via package "C...2016-11-25
  • Android子控件超出父控件的范围显示出来方法

    下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
  • phpStudy访问速度慢和启动失败的解决办法

    下面给大家介绍phpstudy访问速度慢的解决办法。1、修改mysql数据库链接地址为ip地址127.0.0.1。2、使用最新版本,这个坑了我好久时间。下面一段内容是关于phpstudy启动失败的解决办法。php5.3、5.4和apache都是用vc9编...2015-11-24
  • Android开发中findViewById()函数用法与简化

    findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20
  • PHP Curl出现403错误的解决办法

    自己用的小PHP应用,使用curl抓网页下来处理,为了穿墙方便,使用Privoxy作为代理,便于选择哪些网站使用proxy、哪些不用。但今天却遇到了奇怪的问题,访问google baidu这些网站居然都返回403错误,而访问其他的一些网站没事,如果...2014-05-31
  • Android模拟器上模拟来电和短信配置

    如果我们的项目需要做来电及短信的功能,那么我们就得在Android模拟器开发这些功能,本来就来告诉我们如何在Android模拟器上模拟来电及来短信的功能。 在Android模拟...2016-09-20
  • 夜神android模拟器设置代理的方法

    夜神android模拟器如何设置代理呢?对于这个问题其实操作起来是非常的简单,下面小编来为各位详细介绍夜神android模拟器设置代理的方法,希望例子能够帮助到各位。 app...2016-09-20
  • android自定义动态设置Button样式【很常用】

    为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
  • Android WebView加载html5页面实例教程

    如果我们要在Android应用APP中加载html5页面,我们可以使用WebView,本文我们分享两个WebView加载html5页面实例应用。 实例一:WebView加载html5实现炫酷引导页面大多...2016-09-20
  • 深入理解Android中View和ViewGroup

    深入理解Android中View和ViewGroup从组成架构上看,似乎ViewGroup在View之上,View需要继承ViewGroup,但实际上不是这样的。View是基类,ViewGroup是它的子类。本教程我们深...2016-09-20
  • Android自定义WebView网络视频播放控件例子

    下面我们来看一篇关于Android自定义WebView网络视频播放控件开发例子,这个文章写得非常的不错下面给各位共享一下吧。 因为业务需要,以下代码均以Youtube网站在线视...2016-10-02
  • Android用MemoryFile文件类读写进行性能优化

    java开发的Android应用,性能一直是一个大问题,,或许是Java语言本身比较消耗内存。本文我们来谈谈Android 性能优化之MemoryFile文件读写。 Android匿名共享内存对外A...2016-09-20
  • Android设置TextView竖着显示实例

    TextView默认是横着显示了,今天我们一起来看看Android设置TextView竖着显示如何来实现吧,今天我们就一起来看看操作细节,具体的如下所示。 在开发Android程序的时候,...2016-10-02
  • PHP判断上传文件类型的解决办法

    分享给大家php判断上传文件类型的方法,大家一起学习学习。/** * 读取文件前几个字节 判断文件类型 * @return String */ function checkTitle($filename){ $file=fopen($filename, "rb"); $bin=fread($file, 2); /...2015-10-21
  • android.os.BinderProxy cannot be cast to com解决办法

    本文章来给大家介绍关于android.os.BinderProxy cannot be cast to com解决办法,希望此文章对各位有帮助呀。 Android在绑定服务的时候出现java.lang.ClassCastExc...2016-09-20