图片的二级缓存/三级采样

//布局

<?xml version="1.0" encoding="utf-8"?>

<android.support.constraint.ConstraintLayout xmlns:android=“http://schemas.android.com/apk/res/android
xmlns:app=“http://schemas.android.com/apk/res-auto
xmlns:tools=“http://schemas.android.com/tools
android:layout_width=“match_parent”
android:layout_height=“match_parent”
tools:context=".MainActivity">

<Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button"
    android:onClick="click"
    tools:layout_editor_absoluteX="0dp"
    tools:layout_editor_absoluteY="16dp" />

<ImageView
    android:id="@+id/imageView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    tools:layout_editor_absoluteX="16dp"
    tools:layout_editor_absoluteY="138dp"
    tools:srcCompat="@tools:sample/avatars" />

</android.support.constraint.ConstraintLayout>

//代码

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
//记得加权限.图片三级缓存的简化版.
/*图片三级缓存:加载一张图片时, ----Lrucache;DiskLrucache(算法)

  1. 首先先从从内存中加载图片,如果图片不存在,

  2. 他会进入缓存文件里加载.如果说在缓存文件都没有图片.,

  3. 从网络获取图片
    得到这个图片以后:
    a.先把放到内存中,
    b.把图片保存到缓存文件夹中
    图片处理的第三方框架,内部都实现好:*/
    public class MainActivity extends AppCompatActivity {

    private ImageView image;

    Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
    super.handleMessage(msg);
    //通过switch拿到msg.what的值,判断消息的类型
    switch (msg.what) {
    case 1:
    //是1时,得到msg.obj的数据,要进行类型强转换(Bitmap),把Bitmap资源塞给imageView对象,setImageBitmap
    ImageView iv = (ImageView) findViewById(R.id.imageView);
    iv.setImageBitmap((Bitmap)msg.obj);
    break;
    //是2时,弹个吐司."请求失败了
    case 2:
    Toast.makeText(MainActivity.this, “请求失败了”, Toast.LENGTH_SHORT).show();
    break;
    }
    }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    image = findViewById(R.id.imageView);
    }
    public void click(View v){
    //设置字符串放加载网址的字符串
    final String spec =“https://i.loli.net/2017/11/09/5a046546a2a1f.jpg”;
    //new 一个文件对象. getCacheDir()获取缓存目录, 自定义获取文件名的方法.
    /a内部存储:文件权限:默认是私有的,不允许别的应用程序访问
    * 文件存储:应用程序可以把数据存储在自己应用的私有文件夹里面. 存放的路径: /data/data/包名/文件名,数据安全
    获取路径方法: 例子-File file = new File(MainActivity.this.getFilesDir(),“文件名”);
    * 上下文(context).getFileDir() —>/data/data/包名/files/文件名 保存重要配置信息$$$
    * 上下文(context).getCacheDir() —>/data/data/包名/cache/文件名 缓存目录
    /
    final File file = new File(getCacheDir(),getFile(spec));
    boolean exists = file.exists();
    //进行判断,文件是否存在,存在,
    if(exists){
    //通过BitmapFactory,decodeFile方法,参数是文件对象.getAbsolutePath();得到本地缓存的Bitmap对象.
    Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
    //创建message对象,最好用obtainMessage方法得到.
    image.setImageBitmap(bitmap);
    }else{
    //开启一个子线程.
    new Thread(){
    @Override
    public void run() {
    super.run();
    try {
    //1.使用网址封装一个URL对象,new URL(网址)
    URL url = new URL(spec);
    //2.获取连接对象,URL对象urlConnection
    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
    urlConnection.setConnectTimeout(3000);
    int responseCode = urlConnection.getResponseCode();
    if(responseCode == 200){
    //拿到服务器返回的流inputStream
    InputStream inputStream = urlConnection.getInputStream();
    //InputStreamReader reader = new InputStreamReader(inputStream);
    //从流中读取图片的数据,然后把数据保存到本地 new byte[1024]
    byte[] bytes = new byte[1024];
    //定义一个int变量
    int len;
    //定义一个FileOutputStream,传入一个文件对象.
    FileOutputStream fileOutputStream = new FileOutputStream(file);
    //while判断,输入流.read(byte数组),赋给int变量,判断!=-1
    while ((len=inputStream.read(bytes))!=-1){
    fileOutputStream.write(bytes,0,len);
    }
    //关流,此时图片保存到了本地,输入流里已经没有数据了,
    inputStream.close();
    //通过本地路径构造一张位图对象,BitmapFactory.decodeFile(参数文件对象.FileOutputStream拿到绝对路径)
    Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
    //往主线程发送消息,创建message对象.
    Message msg = new Message();
    msg.obj = bitmap;
    msg.what = 1;
    handler.sendMessage(msg);
    }else{
    //如果消息池中有空消息,那么复用空消息
    Message msg = handler.obtainMessage();
    //定义消息的类型,把标识赋予msg.what
    msg.what = 2;
    //把消息发到主线程的消息队列中,sendMessage发送消息.
    handler.sendMessage(msg);
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }.start();
    }
    }
    private String getFile(String ppp){
    //找到"/“所在字符串的位置.url.lastIndexof
    //返回”/",后面的字符串.url.substring(?+1);
    int i = ppp.lastIndexOf("/");
    System.out.println(i+"");
    String s = ppp.substring(i + 1);
    return s;
    }

猜你喜欢

转载自blog.csdn.net/weixin_42791904/article/details/83031591