2019年8月10日13:06:25
应用环境:Anroid 7.0到Android9.0。
先来一张图压压惊:
主线程的概念:我的理解是当你打开Main.java这个Activity类的时候,只要你在这个类里面不要做new Thread().start();这个操作,里面执行的方法都是主线程的。
1.通过Handler Message消息机制访问网络上的图片
实现的原理:
(1)预先在EditText控件上通过EditText#setText()传入要访问的路径资源;
(2)点击按钮就开启一个子线程,在子线程的run()内部进行网络资源的获取,然后将该资源保存到Message对象中,通过Handler#sendMessage(msg)发送资源
(3)发送资源后,在handleMessage(Message msg)这个方法内部进行UI组件的更新操作。例如:ImageView#setBitmapImage(BitmapImage bitmap)
应用相关的源码如下:
Main.java
package com.aaa.a04_getimage; import androidx.appcompat.app.AppCompatActivity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.Toast; import com.aaa.service.ImageService; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.MulticastSocket; import java.net.URL; public class Main extends AppCompatActivity { private ImageView imageView; private EditText editText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); imageView = this.findViewById(R.id.imageView); editText = this.findViewById(R.id.editText); } // 实例化一个Handler处理消息的对象,并且重写处理消息的方法,在这个方法里面完成 UI的更新 Handler handler = new Handler(){ @Override // 处理消息的方法 public void handleMessage(Message msg){ super.handleMessage(msg); imageView.setImageBitmap((Bitmap) msg.obj); } }; // 2019年8月10日12:29:45 子线程 Runnable networkTask = new Runnable() { @Override public void run() { // 请求网络的操作,获取图片 Bitmap bitmap = getImageData(); Message msg = Message.obtain(); msg.obj = bitmap; // 把bitmap赋值给msg对象的obj属性 // msg.what 指定数据的类型,如果指定,等下在处理消息的方法就要在msg.what确定类型 handler.sendMessage(msg); } }; // 2019年8月10日12:29:28 按钮点击事件 主线程 public void getImage(View view){ new Thread(networkTask).start(); // 主线程中开启子线程 } // 业务方法:获取图片的bitmap对象 2019年8月10日12:30:14 public Bitmap getImageData(){ // 在这里进行HTTP request 网络请求相关操作 String path = editText.getText().toString(); // 得到图片的路径 try { URL url = new URL(path); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setConnectTimeout(5000); int code = connection.getResponseCode(); connection.setRequestMethod("GET"); if(code == 200){ InputStream inputStream = connection.getInputStream(); Bitmap bitmap = BitmapFactory.decodeStream(inputStream); return bitmap; } } catch (Exception e) { e.printStackTrace(); } return null; // byte[] data = ImageService.getImage(path); // return BitmapFactory.decodeByteArray(data,0,data.length); } }
main.xml 布局文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/path" /> <EditText android:text="@string/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/editText" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="getImage" android:text="@string/buttonText1"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/imageView"/> </LinearLayout>
string.xml
说明:下面代码中#部分代表的是自己电脑的局域网ip地址(因为我访问的资源在Tomcat服务器上面)。查看自己的ip:按住Windows键+R,输入cmd,在黑窗口中输入ipconfig。
<resources> <string name="app_name">查看网络上的图片</string> <string name="path">图片的网络路径</string> <string name="buttonText">获取资源</string> <string name="editText">http://###.###.###.###:8080/Web/goddess.jpg</string> <string name="buttonText1">查看女神</string> </resources>
效果图如下:
点击 查看女神,图片就显示出来。这里就不截图显示结果了
网络图片的缓存优化
更改Main.java中的内码后如下: