我正在使用OKHttp 3.4.2,我想使用enqueue实现OKHttp异步网络调用。但我必须将数据返回到onPostExecute方法,我在doInBackground中将我的实例变量flower和容器声明为final并尝试但我的应用程序在进行网络调用时崩溃。
同步工作方式
package com.example.async;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.LruCache;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.async.model.Flower;
import java.io.InputStream;
import java.util.List;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class FlowerAdapter extends ArrayAdapter<Flower> {
private Context context;
private List<Flower> flowerList;
private LruCache<Integer, Bitmap> imageCache;
private OkHttpClient client = new OkHttpClient();
public FlowerAdapter(Context context, int resource, List<Flower> objects) {
super(context, resource, objects);
this.context = context;
this.flowerList = objects;
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
imageCache = new LruCache<>(cacheSize);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater =
(LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.item_flower, parent, false);
Flower flower = flowerList.get(position);
TextView tv = (TextView) view.findViewById(R.id.textView1);
tv.setText(flower.getName());
Bitmap bitmap = imageCache.get(flower.getProductId());
if(bitmap != null) {
ImageView image = (ImageView) view.findViewById(R.id.imageView1);
image.setImageBitmap(flower.getBitmap());
} else {
FlowerAndView container = new FlowerAndView();
container.flower = flower;
container.view = view;
ImageLoader loader = new ImageLoader();
loader.execute(container);
}
return view;
}
class FlowerAndView {
public Flower flower;
public View view;
public Bitmap bitmap;
}
private class ImageLoader extends AsyncTask<FlowerAndView, Void, FlowerAndView> {
@Override
protected FlowerAndView doInBackground(FlowerAndView... params) {
FlowerAndView container = params[0];
Flower flower = container.flower;
try{
String imageUrl = MainActivity.BASE_URL + flower.getPhoto();
Request request = new Request.Builder().url(imageUrl).build();
// below response need to be asynchronous using enqueue method
Response response = client.newCall(request).execute();
InputStream inputStream = response.body().byteStream();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
flower.setBitmap(bitmap);
inputStream.close();
container.bitmap = bitmap;
return container;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(FlowerAndView result) {
ImageView image = (ImageView) result.view.findViewById(R.id.imageView1);
image.setImageBitmap(result.bitmap);
imageCache.put(result.flower.getProductId(), result.bitmap);
}
}
}
异步方式无法正常工作 用异步入队方法替换了okhttp execute方法,并在doInBackground中将声明的变量替换为final
package com.example.async;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.LruCache;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.async.model.Flower;
import java.io.InputStream;
import java.util.List;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class FlowerAdapter extends ArrayAdapter<Flower> {
private Context context;
private List<Flower> flowerList;
private LruCache<Integer, Bitmap> imageCache;
private OkHttpClient client = new OkHttpClient();
public FlowerAdapter(Context context, int resource, List<Flower> objects) {
super(context, resource, objects);
this.context = context;
this.flowerList = objects;
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
imageCache = new LruCache<>(cacheSize);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater =
(LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.item_flower, parent, false);
Flower flower = flowerList.get(position);
TextView tv = (TextView) view.findViewById(R.id.textView1);
tv.setText(flower.getName());
Bitmap bitmap = imageCache.get(flower.getProductId());
if(bitmap != null) {
ImageView image = (ImageView) view.findViewById(R.id.imageView1);
image.setImageBitmap(flower.getBitmap());
} else {
FlowerAndView container = new FlowerAndView();
container.flower = flower;
container.view = view;
ImageLoader loader = new ImageLoader();
loader.execute(container);
}
return view;
}
class FlowerAndView {
public Flower flower;
public View view;
public Bitmap bitmap;
}
private class ImageLoader extends AsyncTask<FlowerAndView, Void, FlowerAndView> {
@Override
protected FlowerAndView doInBackground(FlowerAndView... params) {
final FlowerAndView container = params[0];
final Flower flower = container.flower;
try{
String imageUrl = MainActivity.PHOTOS_BASE_URL + flower.getPhoto();
Request request = new Request.Builder().url(imageUrl).build();
//Response response = client.newCall(request).execute();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if(!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
} else {
InputStream inputStream = response.body().byteStream();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
flower.setBitmap(bitmap);
inputStream.close();
// save the bitmap in the container
container.bitmap = bitmap;
}
}
});
return container;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(FlowerAndView result) {
ImageView image = (ImageView) result.view.findViewById(R.id.imageView1);
image.setImageBitmap(result.bitmap);
imageCache.put(result.flower.getProductId(), result.bitmap);
}
}
}