public class SearchAdapter extends SimpleAdapter { private SdCardUtils sdcard = null;
private AsyncImageLoader imageLoader = new AsyncImageLoader();
private Map<Integer, View> viewMap = new HashMap<Integer, View>();
private ViewBinder mViewBinder;
private List<? extends Map<String, ?>> mData; // List列表存放的数据
private int mResource; // 绑定的页面 ,例如:R.layout.search_item,
private LayoutInflater mInflater;
private String[] mFrom; // 绑定控件对应的数组里面的值名称
private int[] mTo; // 绑定控件的ID
Handler myhandler=null;
private Thread thread=null;
// 构造器
public SearchAdapter(Context context, List<? extends Map<String, ?>> data,
int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
mData = data;
mResource = resource;
mFrom = from;
mTo = to;
// 布局泵(LayoutInflater)根据XML布局文件来绘制视图(View)对象。这个类无法直接创建实例,要通过context对象的getLayoutInflater()或getSystemService(String)方法来获得实例,这样获得的布局泵实例符合设备的环境配置。
mInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
} /*
 * SimpleAdapter基类显示每个Item都是通过这个方法生成的 在getView(int position, View
 * convertView, ViewGroup
 * parent)中又调用了SimpleAdapter的私有方法createViewFromResource
 * 来组装View,在createViewFromResource中对SimpleAdapter的参数String[] from 和int[]
 * to进行了组装
 */
public View getView(int position, View convertView, ViewGroup parent) { // 调用下面方法 return createViewFromResource(position, convertView, parent, mResource);
} // 在createViewFromResource方法中又有一个bindView(position,
// v)方法对item中的各个View进行了组装,bindView(position, v)
private View createViewFromResource(int position, View convertView,
ViewGroup parent, int resource) {
View rowView = this.viewMap.get(position); if (rowView == null) {
rowView = mInflater.inflate(resource, null); final int[] to = mTo;
final int count = to.length;
final View[] holder = new View[count]; for (int i = 0; i < count; i++) { holder[i] = rowView.findViewById(to[i]);
}
rowView.setTag(holder);
bindView(position, rowView); // 调用下面方法对Item中的
viewMap.put(position, rowView);
}
return rowView;
} // 对ViewImage进行组装的代码了“else if (v instanceof ImageView)”
@SuppressWarnings("unchecked")
private void bindView(int position, View view) {
final Map dataSet = mData.get(position);
if (dataSet == null) {
return;
} final ViewBinder binder = mViewBinder;
final View[] holder = (View[]) view.getTag();
final String[] from = mFrom;
final int[] to = mTo;
final int count = to.length; for (int i = 0; i < count; i++) {
final View v = holder[i];
if (v != null) {
final Object data = dataSet.get(from[i]);
String urlText = null; if (data == null) {
urlText = "";
} else {
urlText = data.toString();
} boolean bound = false;
if (binder != null) {
bound = binder.setViewValue(v, data, urlText);
} if (!bound) {
if (v instanceof Checkable) {
if (data instanceof Boolean) {
((Checkable) v).setChecked((Boolean) data);
} else {
throw new IllegalStateException(v.getClass()
.getName()
+ " should be bound to a Boolean, not a "
+ data.getClass());
}
} else if (v instanceof TextView) {
setViewText((TextView) v, urlText);
} else if (v instanceof ImageView) {
if (data instanceof Integer) {
setViewImage((ImageView) v, (Integer) data);
} else {
setViewImage((ImageView) v, urlText);
}
} else {
throw new IllegalStateException(
v.getClass().getName()
+ " is not a "
+ " view that can be bounds by this SimpleAdapter");
}
}
}
}
} public void setViewImage(ImageView v, int value) {
v.setImageResource(value);
}

public void setViewImage(final ImageView v,final String url) {


thread = new Thread(){

public void run(){

SdCardUtils sdcard=new SdCardUtils();


try {


if(sdcard.getSdImage(url)!=null){
v.setImageBitmap(sdcard.getSdImage(url));

}
else{
sdcard.downloadFile(url);
v.setImageBitmap(sdcard.getSdImage(url));
}



} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


}
};

thread.start();
}

}我想做一个 图片缓存到本地SD卡上, 这是我的 SimpleAdapter 是在adapter 中处理添加下载图片
但是问题是 报错 android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
请问 如何 解决呢???

解决方案 »

  1.   

    把修改UI的代码放到handle 中
      

  2.   

    //imageView 是你想要实现异步加载的空间 useAble 是在网络加载的图片,在handle里面设置进去
    //变量
    private Handler handler = new Handler();
    private ExecutorService threadPoll = Executors.newFixedThreadPool(5); // 加载主页图片
    private void loadImg(final String url, final ImageView imageView,
    final String dirStr) {
    threadPoll.submit(new Runnable() {
    @Override
    public void run() {
    try {
    final Drawable useAble;
    boolean boo = Utils.testSDPic(url, dirStr);
    // 如果在缓存中没有在SD卡中有的
    if (boo) {
    useAble = Utils.getDrawableSD(url, dirStr,
    CompanyListActivity.this);
    }
    // 如果在缓存中没有在SD卡中也没有的
    else {
    // 网络加载图片加上HOST
    useAble = Utils.getDrawableFromUrl(Constant.HOSTPIC
    + url, CompanyListActivity.this);// 将下载的图片保存到SD卡里面
    if (null != useAble) {
    Utils.savePicSD(url, useAble, dirStr);
    }
    }
    // Thread.currentThread().sleep(200);
    handler.post(new Runnable() {
    @Override
    public void run() {
    if (null != useAble) {
    imageView.setBackgroundDrawable(useAble);
    }
    }
    });
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    });
    }
      

  3.   

    大家有关于ANDROID开发的QQ群吗??
      

  4.   

    你去网上找一个AsynLoadImage的类,网上很多,已经解决了楼主的问题