day4.20总结_异步任务案例和弱引用

一、异步任务案例讲解

1)启动异步任务加载SQLite中的数据

1)AsyncTask.execute(new Runnable{public void run(){}})

2)update UI :runOnUIThread(.....): 不局限于一种写法

例子1:工作线程中更新UI

public class MainActivity extends Activity {

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

        new Thread(){

public void run() {

setTitle("Title01");   

};

}.start();

 

}

 

@Override

protected void onResume() {

// TODO Auto-generated method stub

super.onResume();    onResumeonCreat方法之前执行,那时Activity还没建立

new Thread(){         好检查机制

public void run() {

setTitle("AAAAAA");

};

}.start();

}

public void onClick(View v){

new Thread(){

public void run() {

setTitle("CCCCC");

};

}.start();

}

}

 

2)实现图片的高效加载

例子2:图片压缩

public class MainActivity extends Activity {

 

private ImageView imageView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

imageView=(ImageView) findViewById(R.id.imageView1);

}

public void onClick(View v){

File sdcard=Environment.getExternalStorageDirectory();

File pic=new File(sdcard,"ql.JPG");

//可能会有内存溢出

//imageView.setImageURI(Uri.fromFile(pic));

Bitmap bitMap=decodeSampledBitmapFromResource(pic.getPath(), 300, 200);

imageView.setImageBitmap(bitMap);

}

/**对大图片进行压缩*/

public static Bitmap decodeSampledBitmapFromResource(String  filePath,

int reqWidth, int reqHeight) {

 

//加载图片的边界信息(只读取图片的高度,宽度,不读取具体字节)

// First decode with inJustDecodeBounds=true to check dimensions

final BitmapFactory.Options options =new BitmapFactory.Options();

//将此选项设置true,此时再加载图片就会只读取图片边界信息了。

options.inJustDecodeBounds = true;

//加载图片边界,并将边界信息封装到options对象

BitmapFactory.decodeFile(filePath, options);

 

// Calculate inSampleSize(计算压缩比例)

options.inSampleSize =calculateInSampleSize(options,reqWidth, reqHeight);

 

// Decode bitmap with inSampleSize set

options.inJustDecodeBounds = false;

return BitmapFactory.decodeFile(filePath, options);

}

/**计算压缩比例*/

public static int calculateInSampleSize(

BitmapFactory.Options options, int reqWidth, int reqHeight) {

// Raw height and width of image

//获得实际图片的高度,宽度

final int height = options.outHeight;

final int width = options.outWidth;

int inSampleSize = 1;

 

//通过实际的高度,宽度与我们需要的高度,宽度进行比例运算得到一个压缩比例值

if (height > reqHeight || width > reqWidth) {

if (width > height) {

inSampleSize = Math.round((float)height / (float)reqHeight);

} else {

inSampleSize = Math.round((float)width / (float)reqWidth);

}

}

return inSampleSize;//高度和宽度都按照此比例进行压缩

}

}

 

例子3:图片在工作线程加载

public class MainActivity extends Activity {

 

private ImageView imageView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

    imageView=(ImageView) findViewById(R.id.imageView1);

}

public void onClick(View v){

File sdcard=Environment.getExternalStorageDirectory();

File pic=new File(sdcard,"ql.JPG");

//可能会有内存溢出

//imageView.setImageURI(Uri.fromFile(pic));

new BitmapWorkerTask(imageView).execute(pic.getPath());  调用异步任务

}

/**在工作线程加载并压缩图片:

 * 记住:以后在activity写内部类时,

 * 内部类又是一个线程对象,

 * 请尽量使用静态内部类

 * */

    static class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap>{

private WeakReference<ImageView> wr;

public BitmapWorkerTask(ImageView imageView) {

//构建一个弱引用对象,引用外部类的中的属性imageView

wr=new WeakReference<ImageView>(imageView);

}

@Override

    protected Bitmap doInBackground(String... params) {    压缩方法放在工作线程

    return decodeSampledBitmapFromResource(params[0], 300, 200);

    }

    @Override

    protected void onPostExecute(Bitmap result) {

    if (wr== null && result==null) return;

    ImageView iv=wr.get();         更新UI放在主线程

    if(iv!=null){

    iv.setImageBitmap(result);

    }

    }

}

/**对大图片进行压缩*/

public static Bitmap decodeSampledBitmapFromResource(String  filePath,

        int reqWidth, int reqHeight) {

 

//加载图片的边界信息(只读取图片的高度,宽度,不读取具体字节)

    // First decode with inJustDecodeBounds=true to check dimensions

    final BitmapFactory.Options options =

     new BitmapFactory.Options();

    //将此选项设置true,此时再加载图片就会只读取图片边界信息了。

    options.inJustDecodeBounds = true;

    //加载图片边界,并将边界信息封装到options对象

    BitmapFactory.decodeFile(filePath, options);

    

    // Calculate inSampleSize(计算压缩比例)

    options.inSampleSize =

    calculateInSampleSize(options,

    reqWidth, reqHeight);

 

    // Decode bitmap with inSampleSize set

    options.inJustDecodeBounds = false;

    return BitmapFactory.decodeFile(filePath, options);

}

/**计算压缩比例*/

public static int calculateInSampleSize(

            BitmapFactory.Options options, int reqWidth, int reqHeight) {

    // Raw height and width of image

//获得实际图片的高度,宽度

    final int height = options.outHeight;

    final int width = options.outWidth;

    int inSampleSize = 1;

 

    //通过实际的高度,宽度与我们需要的高度,宽度进行比例运算得到一个压缩比例值

    if (height > reqHeight || width > reqWidth) {

        if (width > height) {

            inSampleSize = Math.round((float)height / (float)reqHeight);

        } else {

            inSampleSize = Math.round((float)width / (float)reqWidth);

        }

    }

    return inSampleSize;//高度和宽度都按照此比例进行压缩

}

}

 

例子4:图片缓存在内存(LruCache)

public class MainActivity extends Activity {

 

private ImageView imageView;

/**定义一个缓存对象,将加载的图片的位图对象进行缓存(缓存到内存)*/

private static LruCache<String,Bitmap> lruCache;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

imageView=(ImageView) findViewById(R.id.imageView1);

        //获取Activity管理器

ActivityManager aManager=(ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);

 

int memorySize=aManager.getMemoryClass(); 系统分配的内存32M

int maxSize=memorySize*1024*1024/8;    转化为字节单位

Log.i("TAG", "memorySize="+memorySize);

lruCache=new LruCache<String,Bitmap>(maxSize){

//计算缓存的每个对象占有的字节数

@Override

protected int sizeOf(String key, Bitmap value) {

return value.getByteCount();

}

};

}

public void onClick(View v){

File sdcard=Environment.getExternalStorageDirectory();

File pic=new File(sdcard,"ql.JPG");

//在此应用中key为图片的地址

Bitmap bitMap=lruCache.get(pic.getPath());

if(bitMap!=null){

Log.i("TAG", "缓存中的图片="+bitMap);

imageView.setImageBitmap(bitMap);

return;

}

Log.i("TAG", "启动异步任务加载图片!");

new BitmapWorkerTask(imageView).execute(pic.getPath());

}

/**在工作线程加载并压缩图片:

 * 记住:以后在activity写内部类时,

 * 内部类又是一个线程对象,

 * 请尽量使用静态内部类

 * */

static class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap>{

private WeakReference<ImageView> wr;

public BitmapWorkerTask(ImageView imageView) {

//构建一个弱引用对象,引用外部类的中的属性imageView

wr=new WeakReference<ImageView>(imageView);

}

@Override

protected Bitmap doInBackground(String... params) {

//加载并压缩大图片

Bitmap bitMap=decodeSampledBitmapFromResource(

params[0], 300, 200);

//缓存图片

lruCache.put(params[0], bitMap);

return bitMap;

}

@Override

protected void onPostExecute(Bitmap result) {

if (wr== null && result==null) return;

ImageView iv=wr.get();

if(iv!=null){

iv.setImageBitmap(result);

}

}

}

 

 

/**对大图片进行压缩*/

public static Bitmap decodeSampledBitmapFromResource(String  filePath,

int reqWidth, int reqHeight) {

 

//加载图片的边界信息(只读取图片的高度,宽度,不读取具体字节)

// First decode with inJustDecodeBounds=true to check dimensions

final BitmapFactory.Options options =

new BitmapFactory.Options();

//将此选项设置true,此时再加载图片就会只读取图片边界信息了。

options.inJustDecodeBounds = true;

//加载图片边界,并将边界信息封装到options对象

BitmapFactory.decodeFile(filePath, options);

 

// Calculate inSampleSize(计算压缩比例)

options.inSampleSize =

calculateInSampleSize(options,

reqWidth, reqHeight);

 

// Decode bitmap with inSampleSize set

options.inJustDecodeBounds = false;

return BitmapFactory.decodeFile(filePath, options);

}

/**计算压缩比例*/

public static int calculateInSampleSize(

BitmapFactory.Options options, int reqWidth, int reqHeight) {

// Raw height and width of image

//获得实际图片的高度,宽度

final int height = options.outHeight;

final int width = options.outWidth;

int inSampleSize = 1;

 

//通过实际的高度,宽度与我们需要的高度,宽度进行比例运算得到一个压缩比例值

if (height > reqHeight || width > reqWidth) {

if (width > height) {

inSampleSize = Math.round((float)height / (float)reqHeight);

} else {

inSampleSize = Math.round((float)width / (float)reqWidth);

}

}

return inSampleSize;//高度和宽度都按照此比例进行压缩

}

 

 

}

 

4)图片缓存在外存(DiskLruCache):????????

 

二、扩展:WeakReferences

1)强引用(Strong References):强引用引用的对象不可被销毁

2)弱引用(WeakReferences):弱引用引用的对象可以被销毁

3)软引用(SoftReferences):软引用引用的对象可以在内存不足时被销毁。

例子5java代码实现弱引用

class ImageView{}

class Activity{

ImageView imageView=new ImageView();

public void onClick(){

new WorkThread(imageView).start();

}

static class WorkThread extends Thread{

private WeakReference<ImageView> wr;

public WorkThread(ImageView imageView) { 用弱引用关联强引用

wr=new WeakReference<ImageView>(imageView);

}

@Override

public void run() {

while(true){

//System.out.println(imageView);

System.out.println("imageView="+wr.get());获取强引用,输出为null

try{sleep(1000);}catch(Exception e){}

}

}

}

@Override

protected void finalize() throws Throwable {回收垃圾时执行

System.out.println("finalize()");

}

}

 

public class WeekReferencesDemo01 {

public static void main(String[] args) {

Activity a=new Activity();

a.onClick();

a=null;

while(true){

System.gc();//通知垃圾回收器,回收垃圾

}

}

}

/**

 * 1)当一个对象被一个强引用引用时,此对象是不会被销毁的

 * 2)当一个对象被一个弱引用引用时,此对象可以被销毁。

 * */

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(day4.20总结_异步任务案例和弱引用)