Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android资产:我应该使用多少加载线程?_Android_Multithreading_Assets - Fatal编程技术网

Android资产:我应该使用多少加载线程?

Android资产:我应该使用多少加载线程?,android,multithreading,assets,Android,Multithreading,Assets,我正在从我的资源/在后台加载位图。 我在网上找到了一些解决方案,但它们为每幅图像都启动了一个新的背景任务 因为我发现它更容易理解,所以我将它改为只有一个加载线程,带有生产者/消费者模式。我对UI线程的请求使用BlockingQueues,并publishProgress进行响应 我的解决方案工作得很好,但它让我怀疑如果我使用多个线程是否会更好。我的代码支持请求失效,但它总是在处理新请求之前完成当前的加载 另一方面:线程不竞争磁盘访问吗 我的代码: package org.example; im

我正在从我的
资源/
在后台加载位图。 我在网上找到了一些解决方案,但它们为每幅图像都启动了一个新的背景任务

因为我发现它更容易理解,所以我将它改为只有一个加载线程,带有生产者/消费者模式。我对UI线程的请求使用
BlockingQueue
s,并
publishProgress
进行响应

我的解决方案工作得很好,但它让我怀疑如果我使用多个线程是否会更好。我的代码支持请求失效,但它总是在处理新请求之前完成当前的加载

另一方面:线程不竞争磁盘访问吗

我的代码:

package org.example;

import android.content.ContextWrapper;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import android.os.AsyncTask;

import android.util.Pair;
import android.widget.ImageView;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;

import java.util.Map;
import java.util.UUID;
import java.util.concurrent.PriorityBlockingQueue;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class ImageLoader extends AsyncTask<Void, Pair<ImageLoader.SetImageTask, Bitmap>, Void> {

    //~ Static fields/initializers -------------------------------------------------------------------------------------

    private static final Logger L = LoggerFactory.getLogger(ImageLoader.class);

    //~ Instance fields ------------------------------------------------------------------------------------------------

    private final Map<String, Bitmap> cache                 = Maps.newHashMap();
    private final ContextWrapper contextWrapper;
    private final PriorityBlockingQueue<LoadTask> loadTasks =
        new PriorityBlockingQueue<ImageLoader.LoadTask>(1, Ordering.arbitrary());

    /* is changed to invalidate tasks */
    private String uuid = null;

    //~ Constructors ---------------------------------------------------------------------------------------------------

    public ImageLoader(final ContextWrapper contextWrapper) {
        this.contextWrapper     = contextWrapper;
        this.uuid               = UUID.randomUUID().toString();
    }

    //~ Methods --------------------------------------------------------------------------------------------------------

    public void invalidateTasks() {
        L.debug("invalidating tasks");
        this.uuid = UUID.randomUUID().toString();
    }

    public void setImage(final ImageView view, final String asset) {
        this.loadTasks.add(new SetImageTask(this.uuid, view, asset));
    }

    public void loadIntoCache(final ImmutableList<String> assets) {
        for (final String asset : assets) {
            this.loadTasks.add(new LoadIntoCacheTask(asset));
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    protected Void doInBackground(Void... param) {
        try {
            while (true) {

                LoadTask task = this.loadTasks.take();
                if (task instanceof SetImageTask) {

                    SetImageTask setImageTask = (SetImageTask) task;
                    if (setImageTask.uuid.equals(this.uuid)) {

                        Bitmap bitmap = this.loadAsset(setImageTask.asset);
                        if (bitmap != null) {
                            this.publishProgress(Pair.create(setImageTask, bitmap));
                        }
                    } else {
                        L.debug("request for asset '{}' outdated", setImageTask.asset);
                    }
                } else {

                    LoadIntoCacheTask cacheTask = (LoadIntoCacheTask) task;
                    Bitmap bitmap               = this.loadAsset(cacheTask.asset);
                    L.debug("storing in cache: '{}'", cacheTask.asset);
                    cache.put(cacheTask.asset, bitmap);
                }
            }
        } catch (final InterruptedException e) {
            L.debug("interrupted -> exiting");
        }

        return null;
    }

    @Override
    protected void onProgressUpdate(Pair<SetImageTask, Bitmap>... results) {

        Pair<SetImageTask, Bitmap> result = results[0];
        if (result.first.uuid.equals(this.uuid)) {
            result.first.view.setImageBitmap(result.second);
        } else {
            L.debug("request for asset '{}' outdated", result.first.asset);
        }
    }

    private Bitmap loadAsset(final String asset) {
        if (this.cache.containsKey(asset)) {
            L.debug("serving from cache '{}'", asset);
            return this.cache.get(asset);

        } else {
            L.debug("loading from assets: '{}'", asset);

            InputStream in = null;
            Bitmap bitmap  = null;
            try {
                in         = new BufferedInputStream(contextWrapper.getAssets().open(asset));
                bitmap     = BitmapFactory.decodeStream(in);
            } catch (final IOException e) {
                L.error(e.getMessage(), e);
            } finally {
                try {
                    in.close();
                } catch (final IOException e) {}
            }

            return bitmap;
        }
    }

    //~ Inner Interfaces -----------------------------------------------------------------------------------------------

    protected static interface LoadTask {}

    //~ Inner Classes --------------------------------------------------------------------------------------------------

    protected static final class SetImageTask implements LoadTask {

        private final String uuid;
        private final ImageView view;
        private final String asset;

        public SetImageTask(final String uuid, final ImageView view, final String asset) {
            this.uuid      = uuid;
            this.view      = view;
            this.asset     = asset;
        }
    }

    protected static final class LoadIntoCacheTask implements LoadTask {

        private final String asset;

        public LoadIntoCacheTask(final String asset) {
            this.asset = asset;
        }
    }
}
package org.example;
导入android.content.ContextWrapper;
导入android.graphics.Bitmap;
导入android.graphics.BitmapFactory;
导入android.os.AsyncTask;
导入android.util.Pair;
导入android.widget.ImageView;
导入com.google.common.collect.ImmutableList;
导入com.google.common.collect.Maps;
导入com.google.common.collect.Ordering;
导入java.io.BufferedInputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入java.util.Map;
导入java.util.UUID;
导入java.util.concurrent.PriorityBlockingQueue;
导入org.slf4j.Logger;
导入org.slf4j.LoggerFactory;
公共最终类ImageLoader扩展异步任务{
//~静态字段/初始值设定项-------------------------------------------------------------------------------------
私有静态最终记录器L=LoggerFactory.getLogger(ImageLoader.class);
//~实例字段------------------------------------------------------------------------------------------------
私有最终映射缓存=Maps.newHashMap();
私有最终ContextWrapper ContextWrapper;
私有最终优先级阻止队列加载任务=
新的PriorityBlockingQueue(1,Ordering.arbitral());
/*更改为使任务无效*/
私有字符串uuid=null;
//~z~施工人员---------------------------------------------------------------------------------------------------
公共图像加载器(最终上下文包装器){
this.contextWrapper=contextWrapper;
this.uuid=uuid.randomUUID().toString();
}
//~方法--------------------------------------------------------------------------------------------------------
公共无效无效tasks(){
L.调试(“使任务失效”);
this.uuid=uuid.randomUUID().toString();
}
public void setImage(最终图像视图,最终字符串资源){
this.loadTasks.add(新的SetImageTask(this.uuid,view,asset));
}
public void loadIntoCache(最终不可变列表资产){
for(最终字符串资产:资产){
this.loadTasks.add(新的LoadIntoCacheTask(资产));
}
}
@抑制警告(“未选中”)
@凌驾
受保护的Void doInBackground(Void…参数){
试一试{
while(true){
LoadTask=this.loadTasks.take();
if(SetImageTask的任务实例){
SetImageTask SetImageTask=(SetImageTask)任务;
if(setImageTask.uuid.equals(this.uuid)){
位图位图=this.loadAsset(setImageTask.asset);
if(位图!=null){
this.publishProgress(Pair.create(setImageTask,位图));
}
}否则{
L.debug(“请求资产{}过时”,setImageTask.asset);
}
}否则{
LoadIntoCacheTask cacheTask=(LoadIntoCacheTask)任务;
位图位图=this.loadAsset(cacheTask.asset);
debug(“存储在缓存中:{}”,cacheTask.asset);
cache.put(cacheTask.asset,位图);
}
}
}捕获(最终中断异常e){
L.调试(“中断->退出”);
}
返回null;
}
@凌驾
受保护的void onProgressUpdate(成对…结果){
配对结果=结果[0];
if(result.first.uuid.equals(this.uuid)){
result.first.view.setImageBitmap(result.second);
}否则{
L.debug(“请求资产{}过时”,result.first.asset);
}
}
私有位图加载资源(最终字符串资源){
if(this.cache.containsKey(资产)){
L.debug(“从缓存“{}”服务,资产);
返回此.cache.get(资产);
}否则{
L.debug(“从资产加载:{}”,资产);
InputStream in=null;
位图=空;
试一试{
in=new BufferedInputStream(contextWrapper.getAssets().open(asset));
位图=BitmapFactory.decodeStream(in);
}捕获(最终IOE例外){
L.错误(如getMessage(),e);
}最后{
试一试{
in.close();
}捕获(最终IOE){}
}
返回位图;
}
}
//~内部接口-----------------------------------------------------------------------------------------------
受保护的静态接口LoadTask{}
//~z~内部阶级--------------------------------------------------------------------------------------------------
受保护的静态最终类SetImageTask实现LoadTask{
私有最终字符串uuid;
私有最终图像视图;
私人最终资产;
公共SetImageTask(最终字符串uuid、最终图像视图、最终字符串资源){
this.uuid=uuid;
this.view=视图;
这个资产=资产;
}
}
受保护的静态最终类LoadI