`
onewayonelife
  • 浏览: 252456 次
  • 性别: Icon_minigender_1
  • 来自: 太原
社区版块
存档分类
最新评论

Android Thread

 
阅读更多

ThreadActivity

package org.wp.activity;

import java.io.InputStream;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.MemoryInfo;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;

public class ThreadActivity extends Activity {
	private Context mContext = null;
	private Handler iHandler = null;
	/** 开始加载图片按钮 **/
	private Button myButton = null;
	/** 显示内存信息 **/
	private TextView miTextView = null;
	/** 显示加载信息 **/
	private TextView liTextView = null;

	/** 获得手机内存信息 **/
	private ActivityManager activityManager = null;
	private MemoryInfo mi = null;

	/** 加载图片进度 **/
	private static final int LOAD_PROGRESS = 0;
	/** 加载图片结束 **/
	private static final int LOAD_COMPLETE = 1;

	/** 加载图片开始时间 **/
	private Long mLoadStartTime = 0L;
	/** 加载图片结束时间 **/
	private Long mLoadEndTime = 0L;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// 设置全屏
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
		// 去掉标题栏
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		// 设置横屏
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
		setContentView(R.layout.thread);
		mContext = this;
		addMessageHandler();

		activityManager = (ActivityManager) mContext
				.getSystemService(Context.ACTIVITY_SERVICE);
		mi = new MemoryInfo();

		miTextView = (TextView) this.findViewById(R.id.miTextView);
		liTextView = (TextView) this.findViewById(R.id.liTextView);
		myButton = (Button) this.findViewById(R.id.myButton);
		myButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				// 加载图片
				loadImage();
			}
		});
	}

	private void addMessageHandler() {
		iHandler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				switch (msg.what) {
				case LOAD_PROGRESS:
					// 加载过程中
					liTextView.setText("当前读取到第" + msg.arg1 + "张图片");
					activityManager.getMemoryInfo(mi);
					miTextView.setText("剩余内存:" + (mi.availMem >> 10) + "K"
							+ "======" + (mi.availMem >> 20) + "M" + "======"
							+ mi.lowMemory);
					break;
				case LOAD_COMPLETE:
					// 记载结束
					liTextView.setText("读取结束一共耗时" + msg.arg1 + "毫秒");
					break;
				}
			}
		};
	}

	private void loadImage() {
		new Thread() {
			public void run() {
				// 加载图片的开始时间
				mLoadStartTime = System.currentTimeMillis();

				// 循环加载2000张图片
				for (int i = 0; i < 2000; i++) {
					readBitmap(mContext, R.drawable.one_piece);
					// 发送加载个数
					Message msg = iHandler.obtainMessage();
					msg.what = LOAD_PROGRESS;
					msg.arg1 = i + 1;
					msg.sendToTarget();
				}

				// 加载图片的结束时间
				mLoadEndTime = System.currentTimeMillis();

				// 发送加载完成信息
				Message msg = iHandler.obtainMessage();
				msg.what = LOAD_COMPLETE;
				msg.arg1 = (int) (mLoadEndTime - mLoadStartTime);
				msg.sendToTarget();
			}
		}.start();
	}

	/**
	 * 尽量不要使用setImageBitmap或setImageResource
	 * 或BitmapFactory.decodeResource来设置一张大图, 
	 * 因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,
	 * 需要消耗更多内存。
	 * 因此,改用先通过BitmapFactory.decodeStream方法,
	 * 创建出一个bitmap,再将其设为ImageView的 source,
	 * decodeStream最大的秘密在于其直接调用 JNI >> nativeDecodeAsset() 来完成decode,
	 * 无需再使用java层的createBitmap,从而节省了java层的空间。
	 * 
	 * 如果在读取时加上图片的Config参数,可以更有效减少加载的内存,
	 * 从而有效阻止抛出out of Memory异常
	 * 另外,decodeStream直接拿的图片来读取字节码了, 不会根据机器的各种分辨率来自动适应,
	 * 使用了decodeStream之后,需要在hdpi和mdpi,ldpi中配置相应的图片资源,
	 * 否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了。
	 * 
	 * BitmapFactory.Options.inPreferredConfig
	 * 
	 * ALPHA_8:数字为8,图形参数应该由一个字节来表示,应该是一种8位的位图
	 * ARGB_4444:4+4+4+4=16,图形的参数应该由两个字节来表示,应该是一种16位的位图.
	 * ARGB_8888:8+8+8+8=32,图形的参数应该由四个字节来表示,应该是一种32位的位图.
	 * RGB_565:5+6+5=16,图形的参数应该由两个字节来表示,应该是一种16位的位图.
	 * 
	 * ALPHA_8,ARGB_4444,ARGB_8888都是透明的位图,也就是所字母A代表透明。
	 * ARGB_4444:意味着有四个参数,即A,R,G,B,每一个参数由4bit表示.
	 * ARGB_8888:意味着有四个参数,即A,R,G,B,每一个参数由8bit来表示.
	 * RGB_565:意味着有三个参数,R,G,B,三个参数分别占5bit,6bit,5bit.
	 * 
	 * 
	 * BitmapFactory.Options.inPurgeable;
	 * 
	 * 如果 inPurgeable 设为True的话表示使用BitmapFactory创建的Bitmap
	 * 用于存储Pixel的内存空间在系统内存不足时可以被回收,
	 * 在应用需要再次访问Bitmap的Pixel时(如绘制Bitmap或是调用getPixel),
	 * 系统会再次调用BitmapFactory decoder重新生成Bitmap的Pixel数组。 
	 * 为了能够重新解码图像,bitmap要能够访问存储Bitmap的原始数据。
	 * 
	 * 在inPurgeable为false时表示创建的Bitmap的Pixel内存空间不能被回收,
	 * 这样BitmapFactory在不停decodeByteArray创建新的Bitmap对象,
	 * 不同设备的内存不同,因此能够同时创建的Bitmap个数可能有所不同,
	 * 200个bitmap足以使大部分的设备重新OutOfMemory错误。
	 * 当isPurgable设为true时,系统中内存不足时,
	 * 可以回收部分Bitmap占据的内存空间,这时一般不会出现OutOfMemory 错误。
	 * 
	 * 
	 * inInputShareable 是否深拷贝 
	 * This field works in conjuction with inPurgeable.
	 * If inPurgeable is false, then this field is ignored. If inPurgeable is
	 * true, then this field determines whether the bitmap can share a reference
	 * to the input data (inputstream, array, etc.) or if it must make a deep copy.
	 * 
	 * @param context
	 * @param resId
	 * @return Bitmap
	 */
	public Bitmap readBitmap(Context context, int resId) {
		BitmapFactory.Options opts = new BitmapFactory.Options();
		opts.inPreferredConfig = Config.RGB_565;
		opts.inPurgeable = true;
		opts.inInputShareable = true;
		InputStream is = context.getResources().openRawResource(resId);
		return BitmapFactory.decodeStream(is, null, opts);
	}
}

 

thread.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent" 
	android:layout_height="fill_parent"
	android:orientation="vertical">
	<Button android:layout_width="fill_parent"
		android:layout_height="wrap_content" 
		android:text="Thread循环加载100张图片"
		android:id="@+id/myButton" />
	<TextView android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:gravity="center"
		android:id="@+id/miTextView" />	
	<TextView android:layout_width="fill_parent"
		android:layout_height="wrap_content" 
		android:gravity="center"
		android:id="@+id/liTextView" />
</LinearLayout>

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics