Trong phần này ta sẽ minh họa một trường hợp tải dữ liệu nhị phân từ máy chủ web thông qua giao thức HTTP. Ta sẽ dùng ứng dụng khung về sử dụng tài nguyên qua HTTP ở trên để tải một ảnh (ảnh là dữ liệu nhị phân) từ trên mạng về và hiển thị bên trong Activity.
Trước tiên ta thêm một đối tượng ImageView vào file layout của Activity để hiển thị ảnh khi được tải về:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ImageView android:id="@+id/img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> </LinearLayout>
Như đã nói ở trên, việc tải tài nguyên từ mạng phải nằm trong thread riêng, khác với thread vẽ giao diện ứng dụng (UI thread). Ở đây ta dùng AsyncTask cho việc này:
private Bitmap DownloadImage(String URL)
{
Bitmap bitmap = null;
InputStream in = null; try {
in = OpenHttpConnection(URL);
bitmap = BitmapFactory.decodeStream(in); in.close();
} catch (IOException e1) {
Log.d("NetworkingActivity", e1.getLocalizedMessage()); }
return bitmap; }
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap>
{
protected Bitmap doInBackground(String... urls) { return DownloadImage(urls[0]);
}
protected void onPostExecute(Bitmap result) {
ImageView img = (ImageView) findViewById(R.id.img); img.setImageBitmap(result);
} }
Hàm DownloadImage thực hiện tải ảnh từ trên mạng về và lưu vào một đối tượng Bitmap (đối tượng này sẵn sàng để đưa vào ImageView). Hàm này sử dụng hàm OpenHttpConnection ta đã làm ở trên để lấy một luồng nhập liệu chứa dữ liệu ảnh này, sau đó dùng hàm tĩnh decodeStream của lớp BitmapFactory để giải mã luồng nhập liệu này và lưu vào đối tượng Bitmap cần thiết.
Tuy nhiên hàm DownloadImage này cũng sẽ chiếm nhiều thời gian (bằng thời gian tải ảnh về của hàm OpenHttpConnection và thời gian giải mã ảnh), vì vậy ta cần gọi hàm này bên trong một thread khác. Trong ví dụ trên ta dùng AsyncTask cho việc này.
Để sử dụng AsyncTask, ta cần nạp chồng tối thiểu 2 hàm:
- doInBackground - hàm này được thực hiện trong thread riêng, khi kết thúc hàm này, nó sẽ tự động gọi hàm onPostExecute trong UI thread. Đây là nơi ta sẽ thực hiện các thao tác tốn thời gian.
-onPostExecute hàm này được gọi trong UI thread, sau khi công việc ngầm ở hàm trên đã kết thúc. Đây là nơi mình cập nhật lại UI từ dữ liệu được tải về.
Trong ví dụ trên, ta sẽ tiến hành tải ảnh trong thread riêng (trong hàm doInBackground) và tiến hành hiển thị ảnh mới được tải về trong hàm onPostExecute.
Cuối cùng, để tiến hành tải ảnh, ta thêm dòng mã gọi đến AsyncTask này trong hàm onCreate của Activity:
@Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new DownloadImageTask().execute("http://www.mayoff.com/5- 01cablecarDCP01934.jpg");
}
Chạy ứng dụng trên điện thoại hoặc Android Emulator, ta sẽ thấy ảnh từ mạng sẽ được hiển thị trên màn hình (có thể phải chờ một lúc nếu kết nối mạng không tốt) như hình minh họa bên dưới:
Phát triển ứng dụng cho thiết bị di động Hồ Thị Thảo Trang
146