Android权威编程指南笔记 第二十五章 HTTP与后台任务(未完)

第二十五章 HTTP与后台任务(未完)

网络连接

  • 由于不能科学上网, 我随便找了个开放的API作为练习, 后面的章节我都是基于这个来做的(结果到了33章还是无法接着, orz)
    https://api.apiopen.top/getImages 可以加上pagecount参数, 代表第几页和返回的图片张数
  • 获取网络权限
    <uses-permission android:name="android.permission.INTERNET"/>
  • 建立连接, 返回byte[] 类型的数组
  1. 创建一个URL对象
  2. 建立连接, 调用URL.openConnection()方法创建一个指向要访问的URL的连接对象, 并强制类型转换成HttpURLConnection
  3. 创建输入. 输出流对象.
  4. 调用InputStream.read(byte[] b)方法, 将输入流读取到数组中, 且返回该数组的长度(int)
  5. 调用ByteArrayOutputStream.write(byte[] b, int off, int len). 写入out输出流中
  6. ByteArrayOutputStream.toByteArray();//创建新分配的字节数组
    public byte[] getUrlBytes(String urlSpec) throws IOException{
        URL url = new URL(urlSpec);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        try{
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            InputStream in = connection.getInputStream();

            if (connection.getResponseCode() != HttpURLConnection.HTTP_OK){
                throw new IOException(connection.getResponseMessage() +
                        ": with " +
                        urlSpec);
            }

            int bytesRead =0;
            byte[] buffer = new byte[1024];
			// read方法:从输入流中读取一些字节数,并将其存储到缓冲区数组buffer中。
			// 实际读取的字节数作为int型返回给bytesRead
            while((bytesRead = in.read(buffer)) > 0){
            //将buffer数组中的数据从以偏移量0开始,以bytesRead为长度,写入out中。
                out.write(buffer, 0, bytesRead);
            }
            out.close();
            return out.toByteArray();//创建新分配的字节数组
        }finally {
            connection.disconnect();
        }
    }
  • 由于要解析为Json格式, 故要返回String类型
        public String getUrlString(String urlSpec) throws IOException{
        return new String(getUrlBytes(urlSpec));//将数组byte[]转化为String
    }

AsyncTask

  • 由于主线程不能运行耗时操作, 所以要在后台进行请求网络, 下载数据等耗时的操作
  • AsyncTask<Params, Progress, Result>
  1. 第一个参数, 可指明转给AsyncTask.execute(...)方法参数的输入类型. 该参数会传入doInBackground(Params), 可传入一个或多个参数
  2. 第二个参数, 可指明转给publishProgress(Progress... values)方法参数的输入类型. 该参数会传入onProgressUpdate(Void... values)
  3. 第三个参数, 是指明doInBackground(Params)返回参数的类型, 返回的参数会传入onPostExecute(Result)
  • publishProgress(Progress... values)doInBackground(Params)方法中执行,该方法会调用onProgressUpdate(Void... values), 且后者在UI线程上调用.
  • onPostExecute(Result)方法在doInBackground(Params)运行完成后调用, 常用于更新UI线程, 避免由于在doInBackground(Params)中更新UI造成内存对象相互践踏, 从而让应用崩溃.
  • AsyncTask的两种使用:
  1. 可以直接创建AsyncTask的对象, 执行AsyncTask.execute(...)时可传入参数
  2. 继承AsyncTask并定义构造函数, 可完成其初始化
    private class FetchItemsTask extends AsyncTask<Void, Void, List<GalleryItem>>{
        private String mPage;
        private String mCount;

        public FetchItemsTask(String page, String count){
            mPage = page;
            mCount = count;
        }


        @Override
        protected List<GalleryItem> doInBackground(Void... voids) {

            //publishProgress(Void... values);
            if (mPage == null||mCount == null){
                return new FlickrFetchr().fetchRecentPhoto();
            }else{
                return new FlickrFetchr().searchPhotos(mPage, mCount);
            }
        }
        
        @Override
        protected void onPostExecute(List<GalleryItem> galleryItems) {
            mItems = galleryItems;
            setupAdapter();
        }

        @Override
        protected void onProgressUpdate(Void... values) {

        }
    }

清理AsyncTask

  • fragment的相关生命周期里清理.(如: onStop()onDestoty())
  • 创建AsyncTask的实例, 然后调用该AsyncTask.cancel(boolean)方法;取消方法有两种:
  1. cancel(true). 立即终止doInBackground(Params), 但在其中的不可终止操作不会自动停止(如: IO流的操作). 可以自己手动停止并抛出异常, 但其就失去了意义.应尽量避免使用
  2. cancel(false), 会将isCancelled()的状态设置为true, 通过判断其值达到终止操作的目的.

获取URI地址(URL地址)

       Uri uri = Uri.parse(String)
             .buildUpon()
             .build();
	String url = Uri.parse("https://...").
		buildUpon().
		appendQueryParameter("提交的键", "相应提取的值").
		build().toString();

Json格式的解析

	JSONObject jsonBody = new JSONObject(String);
	//JSONObject photosJsonObject = jsonBody.getJSONObject("photos"); 
	JSONArray resultJsonArray = photosJsonObject.getJSONArray("photo");
	//遍历resultJsonArray, 取出json对象
	JSONObject jsonObject = resultJsonArray.getJSONObject(i);
	

相关小记

  • 由于AsyncTask可以在后台运行, 因而不能确定fragment是否相关联着activity. 若不关联, 则依赖activity相关的操作都会失效. 故开始要在fragment中用isAdded方法确定activity的存在.

挑战练习

  • 利用Gson工具库解析jJSON
  • 分页
  • 动态调整网格列数(???)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值