使用线程将图像加载到recyclerview

时间:2017-12-27 20:32:16

标签: java android multithreading android-recyclerview

所以我有一个Recyclerview用图像保存项目,我想将图像加载到项目中,但是当我这样做时,我得到了很多fps掉落。 我读到我需要为网络部分使用另一个线程,我试图这样做,你可以看到,这似乎对我好,但我无法弄清楚如何停止fps下降和滚动Recyclerview平滑,Recyclerview应该保持在10到100之间。我应该在一个帖子中运行活动吗?
注意: 10个项目会出现fps下降。

调用OnBindViewHolder中的HttpWrapper.LoadImageFromWebOperations函数。

HomeAdapter.java

public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.HomeViewHolder>{

private Context context;
private ArrayList<RecipeModel> items;

public HomeAdapter(Context context, ArrayList<RecipeModel> items) {
    this.context = context;
    this.items = items;
}

@Override
public HomeAdapter.HomeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(context);
    View v = inflater.inflate(R.layout.home_item,null);
    HomeAdapter.HomeViewHolder holder = new HomeAdapter.HomeViewHolder(v);
    return holder;
}

public void addItem(RecipeModel item){
    this.items.add(item);
    notifyDataSetChanged();
}

@Override
public void onBindViewHolder(HomeAdapter.HomeViewHolder holder, final int position) {
    RecipeModel model = items.get(position);
    holder.name.setText(model.getName());
    holder.directions.setText(model.getDirections()[0]);
    Drawable drawable = HttpWrapper.LoadImageFromWebOperations(model.getImageSource());
    holder.image.setImageDrawable(drawable);
}

@Override
public int getItemCount() {
    return items.size();
}

class HomeViewHolder extends RecyclerView.ViewHolder{
    TextView name;
    TextView directions;
    ImageView image;

    public HomeViewHolder(View itemView) {
        super(itemView);
        name = (TextView) itemView.findViewById(R.id.recipe_name);
        directions = (TextView) itemView.findViewById(R.id.recipe_directions);
        image = (ImageView) itemView.findViewById(R.id.recipe_image);
    }
}

HttpWrapper.java

public class HttpWrapper {

String responseMsg = "";
private OkHttpClient client;
private Request request;
public static final String base_url = "http://kingtimmy.pythonanywhere.com";
public static final String home_route = "/home/";
public HttpWrapper() {
    client = new OkHttpClient();
}
public ArrayList<RecipeModel> get_home_recipes(int recipe_num){
    ArrayList<RecipeModel> models = new ArrayList<RecipeModel>();
    request = new Request.Builder().url(base_url + home_route + String.valueOf(recipe_num)).build();
    responseMsg = "";
    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            responseMsg = "Error: " + e.getMessage();
        }
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            responseMsg = response.body().string();
        }
    });
    while(responseMsg.equals("")){
        continue;
    }
    String[] jsons = responseMsg.split("]-]");
    for (int i = 0; i < jsons.length; i++){
        models.add(makeRecipeModel(jsons[i]));
    }
    return models;
}
public RecipeModel makeRecipeModel(String msg){
    JSONObject nodeRoot = null;
    RecipeModel model;
    try {
        nodeRoot = new JSONObject(msg);
        String[] directions = nodeRoot.get("directions").toString().split("\\n");
        String[] ingredients = nodeRoot.get("ingredients").toString().split("\\n");
        String image_source = nodeRoot.get("image").toString();
        String source_url = nodeRoot.get("source_url").toString();
        String name = nodeRoot.get("name").toString();
        int id = Integer.valueOf(nodeRoot.get("id").toString());
        model = new RecipeModel(directions,ingredients,image_source,source_url,name,id);

    } catch (JSONException e) {
        model = null;
    }
    return model;
}
public static Drawable LoadImageFromWebOperations(final String url) {
    ExecutorService executor = Executors.newSingleThreadExecutor();
    Callable<Drawable> callable = new Callable<Drawable>() {
        @Override
        public Drawable call() {
            try {
                InputStream is = (InputStream) new URL(url).getContent();
                Drawable d = Drawable.createFromStream(is, "src name");
                return d;
            } catch (Exception e) {
                System.out.println("Exc=" + e);
                return null;
            }
        }
    };
    Future<Drawable> future = executor.submit(callable);
    // future.get() returns 2 or raises an exception if the thread dies, so safer
    try {
        Drawable d = future.get();
        executor.shutdown();
        return d;
    } catch (Exception e) {
        return null;
    }
}

我做错了什么?

1 个答案:

答案 0 :(得分:2)

不要编写自己的线程和代码来获取,解析,解码和加载图像,而是尝试Glide。它通过简单的单行代码为您完成所有这些操作,并在ImageView

中加载图像