黑马程序员技术交流社区

标题: 【济南中心】Android课程同步笔记day04:Android应用开发基础 [打印本页]

作者: 小鲁哥哥    时间: 2016-11-19 16:50
标题: 【济南中心】Android课程同步笔记day04:Android应用开发基础
本帖最后由 小鲁哥哥 于 2016-11-19 17:35 编辑


【济南中心】Android课程同步笔记day04:Android应用开发基础

获取网络数据的步骤
首先一定要记得加联网权限<uses-permission android:name="android.permission.INTERNET"/>
[Java] 纯文本查看 复制代码
// 1.得到图片的url路径
URL url = new URL(url_path);
// 2.通过路径打开一个http的连接,并设置请求参数
HttpURLConnection conn = (HttpURLConnection) url.openConnection();// http
// 3.得到响应码,判断与服务器连接是否正常
int code = conn.getResponseCode(); // 200 OK 404 资源没找到 503服务器内部错误
if (code == 200) {
// 4.得到服务器返回的数据流
InputStream is = conn.getInputStream();
}

下面举个简单的联网应用的例子
获取网络图片
布局
[XML] 纯文本查看 复制代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/et_url"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="请输入url" />

    <Button
        android:id="@+id/bt_lookpic"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="获取图片" />

    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="match_parent" >

        <ImageView
            android:id="@+id/img_pic"
            android:layout_width="fill_parent"
            android:layout_height="match_parent" />
    </ScrollView>

</LinearLayout>

代码如下:
[Java] 纯文本查看 复制代码
public class MainActivity extends Activity {

        private EditText mEtUrl;
        private Button mBtLookpic;
        private ImageView mIvPic;
        private Context mContext = this;


        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                initView();
                initListener();
        }

        /**
         * 初始化控件
         */
        private void initView() {
                // 找控件
                mEtUrl = (EditText) findViewById(R.id.et_url);
                mBtLookpic = (Button) findViewById(R.id.bt_lookpic);
                mIvPic = (ImageView) findViewById(R.id.img_pic);
        }

        /**
         * 初始化监听器
         */
        private void initListener() {
                // 设置点击事件
                mBtLookpic.setOnClickListener(new OnClickListener() {

                        @Override
                        public void onClick(View v) {

                                // 获取用户输入的url
                                final String url = mEtUrl.getText().toString().trim();
                                if (TextUtils.isEmpty(url)) {
                                        Toast.makeText(mContext, "url不能为空", 0).show();
                                        return;
                                }
                                // 请求url地址获取源码内容
                                // 创建子线程去请求网络
                                new Thread(new MyTask(url)).start();

                        }
                });
        }

        /**
         * 执行任务
         *
         * @author Somnus
         *
         */
        class MyTask implements Runnable {
                String mUrl;
                public MyTask(String url) {
                        this.mUrl=url;
                }

                @Override
                public void run() {

                        try {
                                // 1.创建Url对象。
                                URL url = new URL(mUrl);
                                // 2.通过Url获取一个HttpUrlConnection对象
                                HttpURLConnection openConnection = (HttpURLConnection) url
                                                .openConnection();
                                // 3.为HttpUrlConnection对象设置请求方式,联网的超时时间
                                openConnection.setRequestMethod("GET");// 请求方式必须大写
                                openConnection.setConnectTimeout(10 * 1000);// 设置超时时间
                                // 4.获取服务器的响应码,判断是否是200
                                int code = openConnection.getResponseCode();
                                if (code == 200) {
                                        // 5.是200,获取流信息,
                                        InputStream inputStream = openConnection.getInputStream();
                                        System.out.println(Utils.StreamToString(inputStream));                                        inputStream.close();
                                }
                        } catch (Exception e) {
                                e.printStackTrace();
                        }

                }
        }
}
上面这段代码我们只是把图片的信息打印出来了,如果说要把图片信息设置给ImageView控件的话就会报“CalledFromWrongThreadException”线程调用异常,就是子线程不能更新UI
ANR异常
上面的代码我们把联网的操作放到了子线中,如果我们联网操作放到了主线程中运行就会导致主线程阻塞导致ANR异常。
ANR全称为Application Not Response 应用程序无响应,一个应用的主线程(又叫UI线程),负责的事情较多,如消息的监听、界面的更新。如果主线程被阻塞,会让整个应用卡住。如果阻塞的时间过长,会导致ANR异常。
如果说我们的耗时操作需要放在子线称中,而在子线程中又不能更新UI界面,那这样是不是就有冲突了?所以谷歌引入了Handler消息机制。


Handler
Handler的使用;
1.主线程中创建一个Handler对象重写handler对象的handlerMessage方法
[Java] 纯文本查看 复制代码
private Handler handler = new Handler(){
                public void handleMessage(android.os.Message msg) {
                };
            };

2.子线程中创建一个message对象
[Java] 纯文本查看 复制代码
//                Message msg = new Message();
                Message msg = Message.obtain();//两个都可以得到Message对象,建议使用obtain,内部是从消息池中取,避免重复创建Message对象

3 .将子线程获取的结果绑定给message对象
[Java] 纯文本查看 复制代码
msg.obj  = result;

4.使用主线程中的handler将子线程中的message发送给主线程
[Java] 纯文本查看 复制代码
handler.sendMessage(msg);

5.主线程中的handleMessage方法接受子线程发来的message,获取绑定的数据,进行UI的更新.
我们通过Handler对上面的代码进行整改更新UI界面
[Java] 纯文本查看 复制代码
public class MainActivity extends Activity {

        private EditText mEtUrl;
        private Button mBtLookpic;
        private ImageView mIvPic;
        private Context mContext = this;
//        1.在主线程中创建一个Handler对象。
        //△△△△△2.实现Handler对象的handleMessage方法。
        private Handler handler = new Handler(){
                public void handleMessage(android.os.Message msg) {
                        //△△△△△6.主线程在handlermesssage方法中接受子线程发来的Message对象,并获取绑定结果数据,进行更新UI的处理
                        Bitmap bitmap = (Bitmap) msg.obj;
                        //将获取的bitmap显示到ImageView上。
                        mIvPic.setImageBitmap(bitmap);
                };
        };

        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                initView();
                initListener();
        }

        /**
         * 初始化控件
         */
        private void initView() {
                // 找控件
                mEtUrl = (EditText) findViewById(R.id.et_url);
                mBtLookpic = (Button) findViewById(R.id.bt_lookpic);
                mIvPic = (ImageView) findViewById(R.id.img_pic);
        }

        /**
         * 初始化监听器
         */
        private void initListener() {
                // 设置点击事件
                mBtLookpic.setOnClickListener(new OnClickListener() {

                        @Override
                        public void onClick(View v) {

                                // 获取用户输入的url
                                final String url = mEtUrl.getText().toString().trim();
                                if (TextUtils.isEmpty(url)) {
                                        Toast.makeText(mContext, "url不能为空", 0).show();
                                        return;
                                }
                                // 请求url地址获取源码内容
                                // 创建子线程去请求网络
                                new Thread(new MyTask(url)).start();

                        }
                });
        }

        /**
         * 执行任务
         *
         * @author Somnus
         *
         */
        class MyTask implements Runnable {
                String mUrl;
                public MyTask(String url) {
                        this.mUrl=url;
                }

                @Override
                public void run() {

                        try {
                                // 1.创建Url对象。
                                URL url = new URL(mUrl);
                                // 2.通过Url获取一个HttpUrlConnection对象
                                HttpURLConnection openConnection = (HttpURLConnection) url
                                                .openConnection();
                                // 3.为HttpUrlConnection对象设置请求方式,联网的超时时间
                                openConnection.setRequestMethod("GET");// 请求方式必须大写
                                openConnection.setConnectTimeout(10 * 1000);// 设置超时时间
                                // 4.获取服务器的响应码,判断是否是200
                                int code = openConnection.getResponseCode();
                                if (code == 200) {
                                        // 5.是200,获取流信息,
                                        InputStream inputStream = openConnection.getInputStream();
                                        // 6.将流信息转换成Bitmap bitmap:位图
                                        Bitmap bitmap = BitmapFactory.decodeStream(inputStream);// 使用BitmapFactory可以将各种资源(文件,流,字节数组)转换成Bitmap对象
                                        inputStream.close();
                                        //△△△△△3.子线程中创建一个Message对象
                                        Message msg = new Message();
                                        //△△△△△4.将子线程中获取的数据绑定给Message对象
                                        msg.obj  = bitmap;
                                        //△△△△△5.使用主线程中的handler对象将子线程message对象发送到主线程
                                        handler.sendMessage(msg);

                                }
                        } catch (Exception e) {
                                e.printStackTrace();
                        }

                }
        }
}



作者: baby14    时间: 2019-6-28 13:27
多谢分享




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2