Android UI线程 HandlerThread 普通线程详解

原创 2015年11月18日 22:13:07

1.安卓的程序执行的入口UI主线程

     所有的Android应用程序组件——包括Activity、Service和Broadcast Receiver,都运行在主线程.因此,任何组件中的耗时操作都将阻塞其它的组件,包括Service和可见的Activity.

  使用后台线程,对于避免第2章中曾描述的“应用程序无响应ANR”对话框的情况是至关重要的.在Android中定义的无响应是指:Activity在5秒内不响应任何输入事件(例如一个按键事件)和Broadcast Receiver在10秒未完成onReceive的处理操作.

  不仅仅是你要避免这种情况,甚至是你都不应该能遇到这种情况.为耗时的处理使用后台线程,包括文件操作、网络搜索、数据库交互和复杂的计算.

2.Thread普通线程

执行耗时操作,避免ANR操作。


3.HandlerThread (重点分析)

a.内部源码实现

b.经典的demo实现,卸载sd卡服务

一.主界面Activity实现

package com.example.testhanlerthread;

import java.lang.reflect.Method;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;
import android.os.storage.IMountService;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;


public class MainActivity extends Activity implements OnClickListener{
	
	
	  public TextView textview;
	  public Button handlerThreadBTN;   
	  HandlerThread handlerThread;  
	  
	  //作为全局变量进行消息的发放和接收到消息的处理
	  Handler handler;

	    @Override
		protected void onCreate(Bundle savedInstanceState) {
	    	
			super.onCreate(savedInstanceState);
			//打印UI线程的名称   
	        System.out.println("onCreate  CurrentThread = " + Thread.currentThread().getName());
	        
			setContentView(R.layout.activity_main);
			textview = (TextView) findViewById(R.id.textView1);
		    handlerThreadBTN = (Button) findViewById(R.id.handlerThreadBtn);
		    
		    handlerThreadBTN.setOnClickListener(this); 
			
			handlerThread = new HandlerThread("myHanler");  
	        handlerThread.start(); 
	        
	        //注意: 这里必须用到handler的这个构造器,因为需要把callback传进去
	        //从而使自己的HandlerThread的handlerMessage来替换掉Handler原生的handlerMessage,对注销的语句解释  
	        //handler = new Handler(handlerThread.getLooper(), handlerThread); 
	        handler = new Handler(handlerThread.getLooper()){
	        	
	        	public void formatSdcard(){
	        		//Phone path
	        		//String sDStateString="/mnt/sdcard";
	        		String sDStateString="/storage/sda1";  //ott path
	        		Method method;
	        		int a=-1;
					try {
				    System.out.println("startformat");
					method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);//利用反射得到ServiceManager类中的getService方法 
	        		IBinder binder = (IBinder) method.invoke(null, "mount");
	        		IMountService iMountService = IMountService.Stub.asInterface(binder);
	        		iMountService.unmountVolume(sDStateString, true,false);//卸载T卡

	        		SystemClock.sleep(4000);
	        		
	        		a=iMountService.formatVolume(sDStateString);
	        		System.out.println(a);
	        		if(a==0){
	        			iMountService.mountVolume(sDStateString);
	        		}
	        		
					} catch (Exception e) {
						System.out.println("输出异常信息="+e.getMessage());
						e.printStackTrace();
					}

	        	}
	        	
	        	@Override  
	            public void handleMessage(Message msg) {
	        		
	        		//格式化Sdcard卡服务
	        		
	        		formatSdcard();
	        		
	            	/*
	        		//子线程执行体
	            	System.out.println(" handleMessage CurrentThread = " + msg.what);
	            	System.out.println(" handleMessage CurrentThread = " + msg.getTarget());
	            	
	                //打印线程的名称 和ID  
	                System.out.println(" handleMessage CurrentThread = " + Thread.currentThread().getName());
	                System.out.println(" handleMessage CurrentThread = " + Thread.currentThread().getId());
	                
	                //textview.setText("hahahahahhahahahah");注意这里是子线程更新UI组件是禁止的,注意HandlerThread
	                //不能用于UI更新
	                Toast.makeText(MainActivity.this, "haha",
	        				Toast.LENGTH_LONG).show();
	        		
	        		*/
	                  
	            }
	        	
	        	
	        	
	        };
		}

	@Override
	public void onClick(View v) {
		
		//点击按钮后来开启线程 ,线程触发指令,想MQ中投递消息
        handler.sendEmptyMessage(1); 
 	
	}

	/*
	private class MyHandlerThread extends HandlerThread implements Callback {  
		  
        public MyHandlerThread(String name) {  
            super(name);  
        }  
  
        @Override  
        public boolean handleMessage(Message msg) {
        	
        	System.out.println(" handleMessage CurrentThread = " + msg.what);
        	System.out.println(" handleMessage CurrentThread = " + msg.getTarget());
        	
            //打印线程的名称 和ID  
            System.out.println(" handleMessage CurrentThread = " + Thread.currentThread().getName());
            System.out.println(" handleMessage CurrentThread = " + Thread.currentThread().getId());
            
            return true;  
        }
        
        */
	}	



二.布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.testhanlerthread.MainActivity$PlaceholderFragment" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <Button
        android:id="@+id/handlerThreadBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textView1"
        android:layout_below="@+id/textView1"
        android:layout_marginTop="99dp"
        android:text="@string/startHandlerThread" />

</RelativeLayout>


三.配置文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testhanlerthread"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />
    <permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS">
    </permission>
    <permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS">
    </permission>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.testhanlerthread.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


四.引入的包

由于sd卡的卸载服务,我们采用了AIDL远端服务,因此我们应该导入包含此服务的android.jar的包,这里还利用了反射机制,进行hide服务的获取情况,因此本例子是一个非常典型的综合服务的情况。

4.异步任务类


5.两种线程以及异步任务类的区别


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Android HandlerThread 完全解析

转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/47079737; 本文出自:【张鸿洋的博客】 1、概述话说最近股市变...

Android 多线程之HandlerThread 完全详解

转载请注明出处(万分感谢!): http://blog.csdn.net/javazejian/article/details/52334098 出自【zejian的博客】 关联文章: A...

Android 建立线程 Thread详细使用方法

转载 1.创建Android线程 参考官方文档是个好习惯。 http://developer.android.com/reference/java/lang/Thread.html ...
  • yqj234
  • yqj234
  • 2014-11-04 14:25
  • 1558

android UI线程和子线程的几种交互方式

我们在进行安卓开发的时候,经常会处理一些耗时的操作,所以经常会开启子线程去执行这些耗时的操作,那么,UI线程怎么和子线程交互的呢,一下提供5种交互方式: 1、handler 2、Activity....

android UI线程讲解

前言本文章主要简单介绍主线程,并且在使用的过程中如何避免ANR异常。当一个应用启动时,系统会为该应用创建一个名为“主线程(或UI 线程)”的执行线程。此线程非常重要,作用如下: 1.它负责将事件分派给...

Android UI绘制之独立线程绘制

在之前

Android 的线程(AsyncTask、HandlerThread、IntentService详解)和线程池

Android 的线程和线程池在操作系统中,线程是操作系统调度的最小单元,同时线程又是一种受限的系统资源,即线程不可能无限制的产生,并且线程的创建和销毁都有一定的开销。

2048游戏回顾四:使用HandlerThread在子线程中更新UI和使用SoundPool播放音效

2048这个游戏的一个特点就是它的UI并不需要实时的去更新,而仅仅是在用户按下左/右/上/下键以后才有可能需要更新UI,UI的跟新往往比较费时,放在主线程会让游戏的操作显得迟缓,因为你必须等它跟新完U...

在Android中使用HandlerThread创建线程

在android开发中,一说起线程的使用,很多人马上想到new Thread(){...}.start()这种方式。 这样使用当然可以,但是多次使用这种方式,会创建多个匿名线程。使得程序运行起来越来...

在Android中使用HandlerThread创建线程

最近用到了HandlerThread,尽管目前一般需要线程的时候很少用HandlerThread,但是在一些场景下还是比较好用的。 在android开发中,一说起线程的使用,很多人马上想到ne...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)