首先,从网络获取资源是不能在UI主线程中进行的,必须要新来一个线程来单独进行网络访问。所以就需要一个自定义的线程MyIntetnetThread,以此来继承Thread ,然后重写方法,来具体编写自己需要的内容。当然还需要一个Handler 来进行消息的传递。
MyInternetThread.java
public class MyInternetThread extends Thread {
private String img_path;
private Handler handler;
private int what;
public MyInternetThread(String img_path, Handler handler, int what) {
this.img_path = img_path;
this.handler = handler;
this.what = what;
}
@Override
public void run() {
getInternetResource();
}
public void getInternetResource(){
try {
URL url = new URL(img_path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
if (connection.getResponseCode() == 200) {
Message message = Message.obtain();
message.obj = connection.getInputStream();
message.what = 1;
handler.sendMessage(message);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
关于message,message.what是进行判断是否下载成功的标志位。
第二,就是在Activity中定义和使用从自定义的线程中拿到的数据。
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if(msg.what==1){
InputStream inputStream = (InputStream) msg.obj;
Bitmap bm=BitmapFactory.decodeStream(inputStream);
String justName = "";
Random random = new Random();
int i = random.nextInt(10000);
justName ="dev_img"+String.valueOf(i)+".jpg";
saveImg(bm, justName);
AppDo_Utils.showToast(getApplicationContext(),"下载成功"+justName);
}else{
AppDo_Utils.showToast(getApplicationContext(),"下载失败");
}
}
};
第三就是拿到的输入流保存成文件就是 saveImg(Bitmap,String);
public void saveImg(Bitmap bm, String fileName) {
File fileDirectory = new File("/sdcard/dev_img/");
if (!fileDirectory.exists()) {
fileDirectory.mkdirs();
}
File ouputFile = new File(fileDirectory, fileName);
try {
FileOutputStream fos = new FileOutputStream(ouputFile);
bm.compress(Bitmap.CompressFormat.JPEG, 85, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
第四就是在UI线程中去启动自定义的线程
new MyInternetThread(realUrl, handler, 0).start();
当然,可以写在一个按钮的点击事件里面
最后,别忘记网络权限和Sdcard读写权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
项目地址:点我就对了