2 freedom wings5 freedom_wings5 于 2016.03.12 20:51 提问

安卓,子线程获取网络图片,发消息给主线程,主线程用图片填充listview,出错

先上logcat:
图片说明

我的xml布局就是一个按钮,和一个listview,listview里就一个imageview,按下按钮开始从网络获取图片,然后发消息到主线程,然后listview就填充数据。xml代码就不贴了。

以下是mainactivity

 public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    Button but;

    Bitmap bitmap;

    ListView listView;
    Bitmap mainBitmap;
    MainHandler mainHandler=new MainHandler();
    List<Map<String,Bitmap>> list=new ArrayList<>();
    Map<String,Bitmap> map;
    Message sendMsg;
    List<Bitmap> bitmapList=new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        but=(Button)super.findViewById(R.id.but);

        img=(ImageView)super.findViewById(R.id.img);
        listView=(ListView)super.findViewById(R.id.listview);

        but.setOnClickListener(this);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    public void onClick(View v)
    {
        new Thread() {
            public void run() {

               List<String> imageList=new ArrayList<>();
                imageList.add("http://i1.hdslb.com/u_user/ed5c9f35b1311b3606c29d633793690b.png");
                imageList.add("http://i1.hdslb.com/u_user/cfdf3c751a554873ecf4687616e1f858.jpg");
                imageList.add("http://i1.hdslb.com/u_user/1462ad43f88a4b6e8b32da2447479f23.jpg");
                try
                {
                    Looper.prepare();

                    for(int i=0;i<imageList.size();i++) {
                        URL uri = new URL(imageList.get(i));
                        HttpURLConnection httpURLConnection = (HttpURLConnection) uri.openConnection();
                        httpURLConnection.setConnectTimeout(5000);
                        httpURLConnection.setUseCaches(false);
                        httpURLConnection.setDoInput(true);
                        InputStream inputStream = httpURLConnection.getInputStream();
                        bitmap = BitmapFactory.decodeStream(inputStream);
                        bitmapList.add(bitmap);
                       }


                    Message sendFinishMessage=Message.obtain();
                    sendFinishMessage.what=2;
                    mainHandler.sendMessage(sendFinishMessage);
                    Looper.loop();

                } catch (Exception e)

                {
                    Log.e("this", "获取网络图片失败" + e);
                }
            }
        }.start();


    }

    class MainHandler extends Handler
    {
        public void handleMessage(Message msg)
        {

            if(msg.what ==2)
            {
                for(int i=0;i<bitmapList.size();i++)
                {

                    map=new HashMap<>();
                    map.put("image",bitmapList.get(i));
                    list.add(map);
                }
                initListView();
            }
        }
    }

    public void initListView()
    {
        SimpleAdapter simpleAdapter=new SimpleAdapter(this,list,R.layout.listview,new String[]{"image"},new int[]{R.id.imageview2});
        listView.setAdapter(simpleAdapter);
    }

}

代码如上,请问是哪里出了问题?

2个回答

mofaji
mofaji   2016.03.13 16:36

看到 日志输出 说找不到文件 应该是在获取网络的图片decode 成bitmap的时候出错
URL uri = new URL(imageList.get(i));
HttpURLConnection httpURLConnection = (HttpURLConnection) uri.openConnection();
httpURLConnection.setConnectTimeout(5000);
httpURLConnection.setUseCaches(false);
httpURLConnection.setDoInput(true);
InputStream inputStream = httpURLConnection.getInputStream();
bitmap = BitmapFactory.decodeStream(inputStream);
bitmapList.add(bitmap);

看来应该是这片代码的问题

lxk_1993
lxk_1993   Rxr 2016.03.18 08:36

for(int i=0;i<imageList.size();i++) {
URL uri = new URL(imageList.get(i));
HttpURLConnection httpURLConnection = (HttpURLConnection) uri.openConnection();
httpURLConnection.setConnectTimeout(5000);
httpURLConnection.setUseCaches(false);
httpURLConnection.setDoInput(true);
InputStream inputStream = httpURLConnection.getInputStream();
bitmap = BitmapFactory.decodeStream(inputStream);
bitmapList.add(bitmap);
}

                                        循环里面加载图片错误 
                                        不是图片地址不能访问 就是 以上代码有问题  你可以参考楼上的代码
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
多线程通信ThreadDemo
实现了子线程与主线程之间的通信;主线程给自己发消息、主线程给子线程发消息、子线程给主线程发消息等。
android 主线程与子线程互发消息,以及自己给自己发消息
使用handler的一点小技巧 使用RUnable接口,然后使用postDeleyed(); 原理是使用ThreadRunable接口来实现 开发步骤:  1、 新建一个Android应用程序  2、 在布局文件中添加2个Button控件标签,并为其设置属性和值  3、 在Activity中,声明控件变量并根据id获得控件对象  4、 在Activity中,创建一个H
Android:主线程如何向子线程发送消息
今天讲一下,在Android中主线程如何向子线程中发送消息的问题。 或许回想无非就是创建一个Handler对象,然后一个线程发消息,另一个接收消息嘛…… 原理确实是这样,但是我们平时,是从子线程向主线程发消息,而主线程默认已经帮我们完成了Looper的操作,所以我们只需要简单的“创建一个Handler对象,然后一个线程发消息,另一个接收消息”…… 我们先说一下这个Looper是神马吧。
Android 使用handler实现线程间发送消息 (主线程 与 子线程之间)、(子线程 与 子线程之间)
关键字:Android 使用handler实现线程间发送消息 (主线程 与 子线程之间)、(子线程 与 子线程之间) 相信大家平时都有使用到异步线程往主线程(UI线程)发送消息的情况。本文主要研究Handler的消息发送。包括主线程往子线程发送消息,子线程之间互相发送消息。 一、主线程向子线程发送消息。 实现过程比较简单: 主线程发送消息到异步线程,异步线程
Android主线程向子线程中发送信息
主要用到了Handler类,Looper类和Message类 先介绍下这几个类 Looper类,是用来为一个线程开启一个消息队列,默认情况下Android下新开启的线程没有开启消息队列的,除了主线程外,主线程系统会默认为其开启一个消息队列;looper是通过MessageQueue来存放消息队列的,一个线程只有一个looper对象,一个messagequeue对象 Handler,通过han
安卓handler的使用
handler的使用演示,主线程给子线程发消息,子线程给主线程发消息
Android:子线程向UI主线程发送消息
在Android里,UI线程是不允许被阻塞的,因此我们要将耗时的工作放到子线程中去处理。 那么子线程耗时处理后要怎样通知UI线程呢?我们可以在UI主线程中创建一个handler对象,然后通过重写其handleMessage(Message msg)的方法,该方法会接收到子线程中的handler对象的sendMessage((Message msg)发回来的消息。这样一发一收就完成工作;而关于主线程
主线程给子线程发送消息
/创建一个子线程,用于主线程向子线程发送消息 class MyThread extends Thread { Handler handler=null; public Handler getHandler(){ return handler; } @Override public void run() { //当子线程给主线程发
Android中主线程给子线程发Message
在Android开发中我们也许常在想主线程如何给子线程发Message?这是一个很好玩的话题通常我们都是在 Activity 中,让子线程执行耗时任务,执行完之后给主线程发送消息让主 线程更新UI。其实还有很多应用场景需要让主线程给子线程发送消息,该消息作为任务的载体,比如在IntentService 中,主线程就给子线程发送了消息,让子线程干活。 给大家写个Demo演示主线程给子线程发送消息
Android中Handler从子线程发消息到主线程回调消息全过程
1.handler是干什么的? 我们在做一些耗时操作的时候,比如网络请求或者操作数据库等等,一般都会在子线程中进行操作,那么一般这些请求完成之后,就要实时刷新界面,而子线程不能刷新页面,只能在主线程进行操作,so,子线程怎么将消息发送到主线程进行页面刷新呢? 2.自己画的一张图,虽然有点丑,不过稍微能说明问题。 第一步:通过sendMessage方法,将消息体发送到