//布局
<?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(算法)
-
首先先从从内存中加载图片,如果图片不存在,
-
他会进入缓存文件里加载.如果说在缓存文件都没有图片.,
-
从网络获取图片
得到这个图片以后:
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;
}