【第21期】观点:人工智能到底用 GPU?还是用 FPGA?

从头学android_网络图片查看器

原创 2016年05月30日 14:32:09

需求:

一个文本框,一个按钮,在文本框中输入一个图片的url,点击按钮,在按钮下方显示图像内容。

layout:

manifest:

申请使用网络的权限

    <uses-permission android:name="android.permission.INTERNET"/>

activity

        String path = editText.getText().toString();
        try {
            URL url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setReadTimeout(8000);
            conn.setConnectTimeout(8000);
            if (conn.getResponseCode() == 200){
                InputStream is = conn.getInputStream();
                Bitmap bitmap = BitmapFactory.decodeStream(is);
                imageView.setImageBitmap(bitmap);
            }else{
                Toast.makeText(MainActivity.this, "url错误", Toast.LENGTH_SHORT).show();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

结果

API14+

但是在API 14 后的android系统中,主线程不允许访问网络,以预防网络耗时所造成的阻塞报错是

android.os.NetworkOnMainThreadException。

那么就用子线程来访问网络吧

        editText = (EditText) findViewById(R.id.et_url);
        imageView = (ImageView) findViewById(R.id.imageView);
        final String path = editText.getText().toString();
        Thread thread = new Thread(){
            @Override
            public void run() {
                try {
                    URL url = new URL(path);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setRequestMethod("GET");
                    conn.setReadTimeout(8000);
                    conn.setConnectTimeout(8000);
                    if (conn.getResponseCode() == 200){
                        InputStream is = conn.getInputStream();
                        Bitmap bitmap = BitmapFactory.decodeStream(is);
                        imageView.setImageBitmap(bitmap);
                    }else{
                        Toast.makeText(MainActivity.this, "url错误", Toast.LENGTH_SHORT).show();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        thread.start();

结果还是不行,报错Only the original thread that created a view hierarchy can touch its views

大致意思应该就是说这个view不是你这个线程创建的,你不能更改它,那么刷新UI就只能在主线程中执行了,但是网络又不能在主线程,如果两个线程直接并行的话,无法保证给ImageView设置Bitmap时,已经拿到了服务器发送的Bitmap,这怎么办呢?

android提供了messageQueue,looper 机制来解决线程间的通信问题,消息队列中存放着消息,一旦有新的消息,轮巡器就会发现,而默认情况下,轮巡器只是发现有新消息,并不做任何事情的,如果我们希望子线程已经得到了Bitmap,发送个主线程一个消息,并附带Bitmap对象,那么就要在主线程中添加一个Handler成员,并且重写它的HandleMessage方法,在这个方法中判断消息是否是子线程发过来的得到Bitmap的消息。当子线程拿到了Bitmap时,用Handler对象发送一个消息,打上标志,附加上Bitmap对象,发送出去,那么消息队列中就会有一个新消息,轮巡器就会发现它,并调用handler的handleMessage方法执行之。真是完美,不得不膜拜谷歌大神的智慧啊!

activity(API14+)

    private final static int GOTBITMAPSUCCESS = 0;
    private final static int WRONGURL = 1;
    private EditText editText;
    private ImageView imageView;

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case GOTBITMAPSUCCESS:
                    Bitmap bm = (Bitmap) msg.obj;
                    imageView.setImageBitmap(bm);
                    break;
                case WRONGURL:
                    Toast.makeText(MainActivity.this, "url错误", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText = (EditText) findViewById(R.id.et_url);
        imageView = (ImageView) findViewById(R.id.imageView);
    }

    public void showImage(View v){
        final String path = editText.getText().toString();
        Thread thread = new Thread(){
            @Override
            public void run() {
                try {
                    URL url = new URL(path);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setRequestMethod("GET");
                    conn.setReadTimeout(8000);
                    conn.setConnectTimeout(8000);
                    if (conn.getResponseCode() == 200){
                        InputStream is = conn.getInputStream();
                        Bitmap bitmap = BitmapFactory.decodeStream(is);

                        Message msg = new Message();
                        msg.what = GOTBITMAPSUCCESS;
                        msg.obj = bitmap;
                        handler.sendMessage(msg);
                    }else{
                        handler.sendEmptyMessage(WRONGURL);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        thread.start();
    }

总结:

1.耗时操作不能放在主线程中,网络是谷歌强制要求剥离主线程的,其他的耗时操作,如读取数据等,应该自觉遵守规范,写在其他线程中去。

2.子线程不能刷新UI,刷新UI必须要用主线程。

3.线程间的通讯可以使用MessageQueue-looper-Handler机制来实现。其中message可以携带对象传送数据。


版权声明:本文为Mr.Seng原创文章,转载注明地址:http://blog.csdn.net/mr_seng 举报

相关文章推荐

Android仿微信朋友圈图片查看器

看博文之前,希望大家先打开自己的微信点到朋友圈中去,仔细观察是不是发现朋友圈里的有个“九宫格”的图片区域,点击图片又会跳到图片的详细查看页面,并且支持图片的滑动和缩放?这个功能是不是很常用呢?!那么我...

Android多媒体学习十一:实现仿百度图片查看功能

我们知道,进入百度图片后,输入一个关键字后,首先看到的是很多缩略图,当我们点击某张缩略图时,我们就可以进入到大图显示页面,在大图显示页面,中包含了一个图片画廊,同时当前大图为刚刚我们点击的那张图片。现...

Android仿微信朋友圈图片查看器

Android仿微信朋友圈图片查看器

android studio for android learning (十三) 一个简单的图片查看器示例

1、程序界面很简单,一个按钮和一个ImageView组件,当用户按下按钮时,程序会自动搜寻/assets/目录下的一张图片。2.在android studio中新建的工程并不存在assets目录,需要...

Android——网络编程(网络图片查看器)

#网络图片查看器 * 确定图片的网址 * 发送http请求     URL url = new URL(address);     //获取连接对象,并没有建立连接     HttpURLConne...

Android 图片查看器

1 http://blog.csdn.net/wang8512945/article/details/8075413 2 http://blog.csdn.net/lcore/article/det...

【Android实战】Gallary+ImageSwicther图片查看器

仿照现在各大新闻网站图片新闻的浏览模式,上面展示具体图片(ImageSwitch),下面是可以滑动的小图片(Gallery)。

Android入门之网络图片查看器

效果图: main.xml
  • acmjk
  • acmjk
  • 2013-08-29 22:52
  • 1199

Android实现网络图片查看器和网页源码查看器

网络图片查看器 清单文加入网络访问权限: |&lt;!-- 访问internet权限 --&gt; | &lt

Android实现网络图片查看器和网页源码查看器

  推荐安卓开发神器(里面有各种UI特效和android代码库实例) <p s
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)