大家好 我是akira上一节 我们讲到使用AsyncTask 这个类进行异步的下载

主要是涉及到一些图片的更新 这次我们继续上一个demo的改进 。

不知道你是否发现一个问题 上一节我们遗留了两个bug 1 在无网络情况下 点击会崩

咱们说 软件开发最忌讳的就是crash 而这个是在bug解决方案中的一级要解决的 所以这个问题

必须搞定 2 就是我们会发现进度并未更新 而图片是显示完毕了的 3 就是一个扩展 这次我将会带来

daimajia的新库 也是做库小达人的最新作品 NumberProgressBar的使用。

1   首先 咱们问题一个一个的解决 首先是第一个 点击会崩溃 那我们就要清楚 why

也就是为什么点击会崩溃 解决这个问题的源头要从原来的代码看起

下面这段代码

 try {  HttpURLConnection connection = (HttpURLConnection) imageUrl.openConnection();  connection.setDoInput(true);  connection.connect();  inputStream =  connection.getInputStream();  downloadImg =  BitmapFactory.decodeStream(inputStream);  }

其实 我们一眼就能看出来 其实就是你如果没网就拿不到流 因为我是没做过图片缓存的 也就是说 每次点击都会去get

没有流 就会造成 inputstream为null 而 再去加载一个null 自然而然 就XXX了   所以 我们找到根源 就是要判断得到的流是否为null

但 仅仅如此么 显然不是 我们最好从源头找到为什么没网 或者说是一个有网的监听 这样最好

说到网 有人自然会想到wifi 说道wifi有人自然会想当然是去想到一个类叫做wifiManager 好 我就满足你的需求

来解析下wifiManager会不会提供一个有没有网的方法 来去判断

先看下wifiManager的实例化

WifiManager manager = (WifiManager) getSystemService(WIFI_SERVICE);
wifiState =  manager.getWifiState();//wifi状态

第一段代码适用于很多的manager 比如inputmanager actvitymanager 等等

而第二句就是很多人想要的那个状态 究竟是不是想要的呢 我们继续往下看

这里面的状态 我也写下来了

private  final int  WIFI_STATE_DISABLING = 0 ;//表示停用中。private  final int  WIFI_STATE_DISABLED  = 1; //表示不可用。private  final int  WIFI_STATE_ENABLING  = 2; //表示启动中。private  final int  WIFI_STATE_ENABLED   = 3; //表示准备就绪。private  final int  WIFI_STATE_UNKNOWN   = 4; //表示未知状态。

看到这个你会想到什么 我第一眼想到的是我自己的网件路由器 这尼玛就是一个网络的加载过程 而且还是wifi的

我们发现最靠谱的启动中似乎也不能满足我们的需求 这个时候有些人也许开始怀疑人生 忘了说

如果你想监听wifi的状态 你还需要加上权限

如下

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

但是 根本的问题还是没解决呀

所以 别怀疑了 咱从头来过吧

这个时候 有人提到了 ConnectivityManager 咦? 这个行不行呢

咱来看看

ConnectivityManager cManager =  (ConnectivityManager)getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo mInfo =  cManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);

yahoo!!! 不错 看起来挺靠谱 继续往下深究

mInfo.isAvailable()

这个api就是告诉你网络是否可用 前面那个type有很多 这里面就说了wifi的 都比较简单 咱就不去官网看了

然后 你想怎么做 是判断当前网络可用就点击么 nono 万一url为空怎么办 考虑到严谨性和代码的健壮性 咱们

要进行并且的判断

并且去设置按钮是否为可点

Button downBtn = (Button) findViewById(R.id.downBtn);if (mInfo.isAvailable() && !TextUtils.isEmpty(url)){downBtn.setClickable(true);downBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {new ImageDownloadTask(MainActivity.this,img,bar).execute(url);}});}else{downBtn.setClickable(false);downBtn.setOnClickListener(null);Toast.makeText(MainActivity.this,"当前无wifi",Toast.LENGTH_SHORT).show();}

OK 外面的逻辑 咱们处理完了 解决了1 crash

PS: 其实这里解决网络很不专业 一般在正式项目里 我们都会写一个广播接受 去观察网络是否可用 这个放到以后

广播的时候再讲

2 关于更新进度 首先 我很清楚一点 如果我要更新一个进度 我肯定要知道一个

总进度 一个当前进度 还有一个通知其刷的这么一个方法

OK 来看关键代码

int totalLength;//总共长度URL imageUrl = null;//图片的urlint length = -1;InputStream inputStream = null;try {imageUrl = new URL(params[0]);HttpURLConnection connection = (HttpURLConnection) imageUrl.openConnection();connection.setDoInput(true);connection.connect();inputStream =  connection.getInputStream();totalLength = connection.getContentLength();if(inputStream!=null){ByteArrayOutputStream baos = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int count = 0;while ((length = inputStream.read(buffer)) != -1) {baos.write(buffer, 0, length);count += length;//这句通知upXXX更新进度publishProgress((int) ((count / (float) totalLength) * 100));}byte[] data=baos.toByteArray();//声明字节数组downloadImg=BitmapFactory.decodeByteArray(data, 0, data. length);return "ok";}}

这里面 咱用一个流去写 然后加载的时候从流利去拿 而总长度有一个getContentLength的方法

最后 刷新 看到那个publishProgress了么 那个就是刷新方法

@Overrideprotected void onProgressUpdate(Integer... progress) {super.onProgressUpdate(progress[0]);mBar.setProgress(progress[0]);Log.e("akira",progress[0]+"...");}

同样 这里进行刷新 注意 progress是一个可变数组

下面我用log打印了下 不打印无所谓

最后post方法没修改

3

daimajia的库 首先 我们需要找到daimajia的库

以下url

https://github.com/daimajia/NumberProgressBar

写的已经非常非常非常清楚了

Eclipse和andriodstudio都有各自的导入方式 就不赘述了

有些如果你发现你导入之后 找不到style 你可以手动去拷它里面的样式

下面是我的layout代码

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:custom="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:id="@+id/hello"android:text="@string/hello_world" android:layout_width="wrap_content"android:layout_height="wrap_content" /><Buttonandroid:layout_below="@id/hello"android:id="@+id/downBtn"android:text="down"android:textSize="20sp"android:textColor="@android:color/black"android:layout_width="match_parent"android:layout_height="wrap_content" /><ImageViewandroid:layout_centerInParent="true"android:layout_below="@id/downBtn"android:id="@+id/img"android:layout_width="wrap_content"android:layout_height="wrap_content"android:scaleType="fitXY"android:visibility="gone"/><com.daimajia.numberprogressbar.NumberProgressBarstyle="@style/NumberProgressBar_Funny_Orange"android:id="@+id/bar"android:layout_centerInParent="true"android:layout_width="wrap_content"android:layout_height="wrap_content"android:visibility="gone"/><!--<ProgressBarandroid:id="@+id/bar"android:layout_centerInParent="true"android:layout_width="wrap_content"android:layout_height="wrap_content"android:visibility="gone"/>--></RelativeLayout>

这里面 你会发现 我的custom命名空间没有用到 为毛 因为我把有些东西全部用一个style代表了

不行你看

<style name="NumberProgressBar_Funny_Orange"><item name="android:layout_height">wrap_content</item><item name="android:layout_width">match_parent</item><item name="max">100</item><item name="progress">0</item><item name="progress_unreached_color">#CCCCCC</item><item name="progress_reached_color">#FF530D</item><item name="progress_text_size">10sp</item><item name="progress_text_color">#FF530D</item><item name="progress_reached_bar_height">1.5dp</item><item name="progress_unreached_bar_height">0.75dp</item></style>

这里面 你会发现 他定义了 宽高 max 进度 颜色 和字体颜色 大小等等

所以直接用就可以了

main代码修改

public class MainActivity extends Activity {String url ;private  final int  WIFI_STATE_DISABLING = 0 ;//表示停用中。private  final int  WIFI_STATE_DISABLED  = 1; //表示不可用。private  final int  WIFI_STATE_ENABLING  = 2; //表示启动中。private  final int  WIFI_STATE_ENABLED   = 3; //表示准备就绪。private  final int  WIFI_STATE_UNKNOWN   = 4; //表示未知状态。private  NetworkInfo mInfo;private ConnectivityManager cManager;private Button downBtn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);if(TextUtils.isEmpty(url))url = "http://bbra.cn/Uploadfiles/imgs/20110303/fengjin/015.jpg";final NumberProgressBar bar = (NumberProgressBar) findViewById(R.id.bar);final ImageView img = (ImageView) findViewById(R.id.img);final WifiManager manager = (WifiManager) getSystemService(WIFI_SERVICE);int wifiState =  manager.getWifiState();//wifi状态cManager = (ConnectivityManager)getSystemService(CONNECTIVITY_SERVICE);mInfo =  cManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);downBtn = (Button) findViewById(R.id.downBtn);if (mInfo.isAvailable() && !TextUtils.isEmpty(url)){downBtn.setClickable(true);downBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {new ImageDownloadTask(MainActivity.this,img,bar).execute(url);}});}else{downBtn.setClickable(false);downBtn.setOnClickListener(null);Toast.makeText(MainActivity.this,"当前无wifi",Toast.LENGTH_SHORT).show();}}}

ImageDownXXX代码修改

/*** Created by akira on 2015/1/27.*/
public class ImageDownloadTask extends AsyncTask<String,Integer,String> {private Bitmap downloadImg;private NumberProgressBar mBar;private Context mContext;private ImageView netImageView;private int perPro;//递增的进度public ImageDownloadTask(Context context, ImageView imageView, NumberProgressBar bar){this.mContext = context;this.netImageView = imageView;this.mBar = bar;mBar.incrementProgressBy(perPro);}@Overrideprotected void onPreExecute() {
//        super.onPreExecute();mBar.setVisibility(View.VISIBLE);}@Overrideprotected String doInBackground(String... params) {int totalLength;//总共长度URL imageUrl = null;//图片的urlint length = -1;InputStream inputStream = null;try {imageUrl = new URL(params[0]);HttpURLConnection connection = (HttpURLConnection) imageUrl.openConnection();connection.setDoInput(true);connection.connect();inputStream =  connection.getInputStream();totalLength = connection.getContentLength();if(inputStream!=null){ByteArrayOutputStream baos = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int count = 0;while ((length = inputStream.read(buffer)) != -1) {baos.write(buffer, 0, length);count += length;//这句通知upXXX更新进度publishProgress((int) ((count / (float) totalLength) * 100));}byte[] data=baos.toByteArray();//声明字节数组downloadImg=BitmapFactory.decodeByteArray(data, 0, data. length);return "ok";}} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}return null;}@Overrideprotected void onProgressUpdate(Integer... progress) {super.onProgressUpdate(progress[0]);mBar.setProgress(progress[0]);Log.e("akira",progress[0]+"...");}@Overrideprotected void onPostExecute(String result) {
//        super.onPostExecute(s);mBar.setVisibility(View.GONE);netImageView.setVisibility(View.VISIBLE);netImageView.setImageBitmap(downloadImg);Toast.makeText(mContext,"加载完毕",Toast.LENGTH_LONG).show();}
}

究竟行不行 来运行运行吧

什么 你没看起清楚? 没事 onemoretime!

OK  三个问题搞定 下一次 咱们来动态设置progress的style 以及写一个自己的progressbar

各位下期再会!

学习andriod开发之 异步加载图片(二)--- 使用其他进度条相关推荐

  1. Android之使用Android-AQuery异步加载图片(一)

    第一节:转载地址(http://www.cnblogs.com/lee0oo0/archive/2012/10/25/2738299.html) // 必须实现AQuery这个类 AQuery aq ...

  2. android开发小技巧:实现listview异步加载图片

    2019独角兽企业重金招聘Python工程师标准>>> 针对listview异步加载图片这个问题,麦子学院android开发老师讲了一种非常实用的方法,麦子学院android开发老师 ...

  3. android开发学习之路——连连看之加载图片(三)

    正如前面AbstractBoard类的代码中看到的,当程序需要创建N个Piece对象时,程序会直接调用ImageUtil的getPlayImages()方法去获取图片,该方法将会随机从res\ dra ...

  4. Android 开发笔记 ListView异步加载图片

    当ListView需要在线获取数据,并且列表中需要显示图片时,友好的处理方式是使用异步加载图片的方式. 这是因为LIstView中显示的内容是分为两部加载的,第一次加载文本信息(包含图片的uri地址) ...

  5. [置顶] 异步加载图片,使用LruCache和SD卡或手机缓存,效果非常的流畅

    转载请注明出处http://blog.csdn.net/xiaanming/article/details/9825113 异步加载图片的例子,网上也比较多,大部分用了HashMap<Strin ...

  6. Android开发之ListView异步加载图片

    ListView这个控件对于大家肯定不会陌生,即使你是初学者相信也会用ListView.因为ListView这个控件实在是太常用,可以说基本上每一个项目开发都会用到它,今天这篇博客主要讲解,ListV ...

  7. Android ListView异步加载图片乱序问题,原因分析及解决方案

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/45586553 在Android所有系统自带的控件当中,ListView这个控件算是 ...

  8. android grideview 图片png透明,Android完美解决GridView异步加载图片和加载大量图片时出现Out Of Memory问题...

    众所周知,我们在使用GridView或者ListView时,通常会遇到两个棘手的问题: 1.每个Item获取的数据所用的时间太长会导致程序长时间黑屏,更甚会导致程序ANR,也就是Application ...

  9. Android之ListView异步加载图片且仅显示可见子项中的图片

    折腾了好多天,遇到 N 多让人崩溃无语的问题,不过今天终于有些收获了,这是实验的第一版,有些混乱,下一步进行改造细分,先把代码记录在这儿吧. 网上查了很多资料,发现都千篇一律,抄来抄去,很多细节和完整 ...

  10. iOS开发 关于tableView加载图片时出现卡顿时的解决办法

    新手做开发的时候一般都会遇到使用tableView从网上加载图片并显示图文的时候会有卡顿现象,而这种卡顿现象也是因为多种原因造成的.一般可以分为两种:一种是由于网上加载图片需要动态定义cell的高度( ...

最新文章

  1. 基于Co-Attention和Co-Excitation的少样本目标检测 | NeurIPS 2019
  2. LINQ系列:Linq to Object分区操作符
  3. python网络爬虫的基本步骤-详解Python网络爬虫功能的基本写法
  4. 【正一专栏】新赛季欧冠小组赛猜想
  5. Centos iptables常用命令及设置
  6. Django学习手册 - ORM数据类型
  7. 有趣!机器学习预测《守望先锋》里的赢家
  8. 电动汽车告急?特斯拉、蔚来之后 一辆比亚迪新能源车突然自燃...
  9. 拒绝无用的长篇大论!仅12张图片,最全的中台精华都在这里了
  10. Spring MVC 入门指南(二):@RequestMapping用法详解
  11. informix数据库启动/停止
  12. Django积木块11 —— 缓存
  13. Ubuntu命令参考手册
  14. 74 系列COMS系列逻辑器件芯片功能大全
  15. php 图片抠图,php抠图教程(混合模式+剪切蒙版)
  16. DataFrame 修改列名
  17. 做视频直播时如何测试本地网络的上行带宽(网速测试)
  18. 火车采集器采集内容页分页教程
  19. 视频教程-5小时零基础入门小程序云开发-微信开发
  20. 公司上市需要具备的条件有哪些

热门文章

  1. 【教程】一个国外的apk镜像网站,支持下载google play等软件
  2. 态度决定一切《跟任何人都聊得来》
  3. 自学量化投资之旅-学习第一个策略EMV指标
  4. 华为智慧屏鸿蒙20,华为智慧屏SE系列首销 搭载鸿蒙分布式跨屏技术
  5. 通过香港招行一卡通收回PayPal资金
  6. 新一代消息中间件—Apache Pulsar
  7. Window和WindowManager--《Android开发艺术探索》阅读笔记——第八章
  8. 完全指南:在 Linux 中如何打印和管理打印机
  9. 科大奥锐密立根油滴实验数据_密立根油滴实验数据处理
  10. Cadence封装尺寸总结