高仿新闻教程之异步更新数据(10)

对于异步和handler的要求 。面试有很高的要求,对于这一节我也不是很清楚,不过我会边写边梳理我的思路,尽量在我讲的时候,顺便把这一节内容一起讲完。


今天是我写这一篇教程第十版,深圳的11月很凉爽,其实写着一篇教程我同时也在梳理我的思路,我是一个小菜鸟,只能写出基本的程序结构,不过现在打基础,后面还有很多精彩的开源项目,等着我们开发,我们要压抑着这份惊喜,好好的打基础

谷歌公司为什么会出现异步,因为为了保证APP的流畅性,所以谷歌就在架构中加入,如果过多耗时操作在主线程执行就会报异常,或者直接down,然后给开发者提供了一套教程,当然这时候开发者就应该想你不让我在主线程耗时,那我就开启子线程更新呗,这时候问题来了..........................

子线程执行的耗时操作的结果不能在UI更新,这时候,开发者就要想了,那就把数据传给UI线程更新呗,当然这是消息机制了,这时候,谷歌肯定是有进步的,这不就有了把东西全部封装好,开发者直接调用方法就行了。


以上是我猜的............. 结果谷歌官方给出的解释呢  你猜是不是这样的


官方解释

android提供了一套专门用于异步处理的类。即:AynsTask类。使用这个类可以为耗时程序开辟一个新线程进行处理,处理完时返回。


其实对于谷歌这个德行大家习惯就好,谷歌并不比我们聪明多少,但是关键java的三大特性 是啥 封装 继承 多态  这就给了谷歌时间,给一些基层的东西不断封装成一个工具类,继承和多态证明了扩展性,这个现在已经成了安卓系统了不是。


AsynTask类就是对Thread类的一个封装,并且加入了一些新的方法。编程时,两者都可以实现同样的功能。本文后面将对AsynTask和Thread进行比较。


AsynTask类结构
asysTask类主要用到的几个内部回调函数有:

怎么感觉再写下去专门写 异步的了,回到原题

onPreExecute()

1.主线程调用AsynTask子类实例的execute()方法后,首先会调用onPreExecute()方法。onPreExecute()在主线程中运行,可以用来写一些开始提示代码。

    // 隐藏刷新按钮
            mTitlebarRefresh.setVisibility(View.GONE);
            // 显示进度条
            mLoadnewsProgress.setVisibility(View.VISIBLE);
            // 设置LoadMore Button 显示文本
            loadMoreBtn.setText(R.string.loadmore_txt);
doInBackGround()

2.之后启动新线程,调用doInBackground()方法,进行异步数据处理。

在这里刷新界面~~~~

    return getSpeCateNews((Integer) params[0], mNewsData,
                    (Integer) params[1], (Boolean) params[2]);

onPostExecute()

3.处理完毕之后异步线程结束,在主线程中调用onPostExecute()方法。onPostExecute()可以进行一些结束提示处理。

UI更新 

        // 根据返回值显示相关的Toast

    switch (result) {
            case NONEWS:
                Toast.makeText(MainActivity.this, R.string.no_news,
                        Toast.LENGTH_LONG).show();
                break;
            case NOMORENEWS:
                Toast.makeText(MainActivity.this, R.string.no_more_news,
                        Toast.LENGTH_LONG).show();
                break;
            case LOADERROR:
                Toast.makeText(MainActivity.this, R.string.load_news_failure,
                        Toast.LENGTH_LONG).show();
                break;
            }

            mNewsListAdapter.notifyDataSetChanged();
            // 显示刷新按钮
            mTitlebarRefresh.setVisibility(View.VISIBLE);
            // 隐藏进度条
            mLoadnewsProgress.setVisibility(View.GONE);
            // 设置LoadMore Button 显示文本
            loadMoreBtn.setText(R.string.loadmore_btn);

onProgressUpdate()

4.在doInBackground()方法异步处理的时候,如果希望通知主线程一些数据(如:处理进度)。这时,可以调用publishProgress()方法。这时,主线程会调用AsynTask子类的onProgressUpdate()方法进行处理

这个时候 我们就完成了一个 异步加载新闻了,主要是通过点击刷新按钮 来实现的.

再看异步这个类

    private class LoadNewsAsyncTask extends AsyncTask<Object, Integer, Integer>

AsynTask类在继承时要传入3个泛型。

第一个泛型对应execute()向doInBackground()的传递类型。

第二个泛型对应doInBackground()的返回类型和传递给onPostExecute()的类型。

第三个泛型对应publishProgress()向progressUpdate()传递的类型。

在这里之前我们跟handler 对比一下 ~~~~~~~~~~~~~~我是淫荡的分割线~~~~~~~~~~~~~~~~~~~~~~~~~

初次看到这个异步调用关系可能觉得很复杂,但其实熟悉了之后会发现这种结构很好用。这种结构将所有的线程通信都封装成回调函数,调用逻辑容易书写。尤其是在异步处理结束之后,有回调函数进行收尾处理。如果是使用Thread的run()方法,run()结束之后没有返回值。所以必须要自己建立通信机制。但是,其实使用Handler+Thread机制其实完全可以替代AsynTask的这种调用机制。只要将Handler对象传给Thread,就可以进行方便的异步处理。且这种MVC模式结构更加明显,方便管理。所以我觉得,使用asynTask还是Handler+Thread结构,个人喜好吧。但是有一点可以明显能感觉到得是,Handler+Thread适合进行大框架的异步处理,而asynTask适用于小型简单的异步处理。


好了开始写我们的代码吧
首先是对于我们的button 实例化,并且添加事件处理 我要的效果就是点刷新的时候,顺便将刷新的button 更换为 progressbar

		<Button
			android:id="@id/titlebar_refresh"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:background="@drawable/titlebar_btn_refresh_selector"
			android:layout_marginTop="7.0dip"
			android:layout_marginRight="14.0dip"
			android:layout_alignParentRight="true"
			/>
		<ProgressBar
			android:id="@+id/loadnews_progress"
			android:layout_width="25.0dip"
			android:layout_height="25.0dip"
			android:clickable="false"
			android:visibility="gone"
			android:layout_marginRight="20.0dip"
			android:layout_marginTop="10.0dip"
			android:layout_alignParentRight="true"
			style="?android:attr/progressBarStyleLarge" />

大家可以看出 我刷新的button正常是显示的  progressbar是隐藏的 当你点击的时候,就会 progressbar显示 刷新的button隐藏

实例化button  和progressbar

mTitlebarRefresh = (Button) findViewById(R.id.titlebar_refresh);
		mLoadnewsProgress = (ProgressBar) findViewById(R.id.loadnews_progress);
		mTitlebarRefresh.setOnClickListener(loadMoreListener);

然后再是就是异步的开启  然后把所有更新UI的操作都放在异步。

	private OnClickListener loadMoreListener = new OnClickListener() {
		@Override
		public void onClick(View v) {
			loadNewsAsyncTask = new LoadNewsAsyncTask();
			switch (v.getId()) {
			case R.id.loadmore_btn:
				// 获取该栏目下新闻
				// getSpeCateNews(mCid,mNewsData,mNewsData.size(),false);
				// 通知ListView进行更新
				// mNewsListAdapter.notifyDataSetChanged();ww
				loadNewsAsyncTask.execute(mCid, mNewsData.size(), false);
				break;
			case R.id.titlebar_refresh:
				loadNewsAsyncTask.execute(mCid, 0, true);
				break;
			}
		}
	};

然后再看 异步类

private class LoadNewsAsyncTask extends AsyncTask<Object, Integer, Integer> {

		@Override
		protected void onPreExecute() {
			// 隐藏刷新按钮
			mTitlebarRefresh.setVisibility(View.GONE);
			// 显示进度条
			mLoadnewsProgress.setVisibility(View.VISIBLE);
			// 设置LoadMore Button 显示文本
			loadMoreBtn.setText(R.string.loadmore_txt);
		}

		@Override
		protected Integer doInBackground(Object... params) {
			return getSpeCateNews((Integer) params[0], mNewsData,
					(Integer) params[1], (Boolean) params[2]);
		}

		@Override
		protected void onPostExecute(Integer result) {
			// 根据返回值显示相关的Toast
			switch (result) {
			case NONEWS:
				Toast.makeText(MainActivity.this, R.string.no_news,
						Toast.LENGTH_LONG).show();
				break;
			case NOMORENEWS:
				Toast.makeText(MainActivity.this, R.string.no_more_news,
						Toast.LENGTH_LONG).show();
				break;
			case LOADERROR:
				Toast.makeText(MainActivity.this, R.string.load_news_failure,
						Toast.LENGTH_LONG).show();
				break;
			}
			mNewsListAdapter.notifyDataSetChanged();
			// 显示刷新按钮
			mTitlebarRefresh.setVisibility(View.VISIBLE);
			// 隐藏进度条
			mLoadnewsProgress.setVisibility(View.GONE);
			// 设置LoadMore Button 显示文本
			loadMoreBtn.setText(R.string.loadmore_btn);
		}
	}

关于异步 基本就是我的那个思想基础就好

点击下载源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值