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

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

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

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

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

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

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

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

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

下面这段代码

[cpp]  view plain copy
  1. try {    
  2.            HttpURLConnection connection = (HttpURLConnection) imageUrl.openConnection();    
  3.            connection.setDoInput(true);    
  4.            connection.connect();    
  5.            inputStream =  connection.getInputStream();    
  6.            downloadImg =  BitmapFactory.decodeStream(inputStream);    
  7.    
  8.        }  
其实 我们一眼就能看出来 其实就是你如果没网就拿不到流 因为我是没做过图片缓存的 也就是说 每次点击都会去get

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

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

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

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

先看下wifiManager的实例化

[java]  view plain copy
  1. WifiManager manager = (WifiManager) getSystemService(WIFI_SERVICE);  
  2. wifiState =  manager.getWifiState();//wifi状态  
第一段代码适用于很多的manager 比如inputmanager actvitymanager 等等 

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

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

[java]  view plain copy
  1. private  final int  WIFI_STATE_DISABLING = 0 ;//表示停用中。  
  2.     private  final int  WIFI_STATE_DISABLED  = 1//表示不可用。  
  3.     private  final int  WIFI_STATE_ENABLING  = 2//表示启动中。  
  4.     private  final int  WIFI_STATE_ENABLED   = 3//表示准备就绪。  
  5.     private  final int  WIFI_STATE_UNKNOWN   = 4//表示未知状态。  
看到这个你会想到什么 我第一眼想到的是我自己的网件路由器 这尼玛就是一个网络的加载过程 而且还是wifi的 

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

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

如下

[java]  view plain copy
  1. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />  
  2.    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />  

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

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

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

咱来看看

[java]  view plain copy
  1. ConnectivityManager cManager =  (ConnectivityManager)getSystemService(CONNECTIVITY_SERVICE);  
  2. NetworkInfo mInfo =  cManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);  

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

[java]  view plain copy
  1. mInfo.isAvailable()  

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

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

要进行并且的判断

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

[java]  view plain copy
  1. Button downBtn = (Button) findViewById(R.id.downBtn);  
  2.         if (mInfo.isAvailable() && !TextUtils.isEmpty(url)){  
  3.                 downBtn.setClickable(true);  
  4.                 downBtn.setOnClickListener(new View.OnClickListener() {  
  5.                 @Override  
  6.                 public void onClick(View view) {  
  7.                     new ImageDownloadTask(MainActivity.this,img,bar).execute(url);  
  8.   
  9.                 }  
  10.              });  
  11.         }else{  
  12.             downBtn.setClickable(false);  
  13.             downBtn.setOnClickListener(null);  
  14.             Toast.makeText(MainActivity.this,"当前无wifi",Toast.LENGTH_SHORT).show();  
  15.         }  


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

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

广播的时候再讲

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

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

OK 来看关键代码

[html]  view plain copy
  1. int totalLength;//总共长度  
  2.         URL imageUrl = null;//图片的url  
  3.         int length = -1;  
  4.         InputStream inputStream = null;  
  5.         try {  
  6.             imageUrl = new URL(params[0]);  
  7.             HttpURLConnection connection = (HttpURLConnection) imageUrl.openConnection();  
  8.             connection.setDoInput(true);  
  9.             connection.connect();  
  10.             inputStream =  connection.getInputStream();  
  11.             totalLength = connection.getContentLength();  
  12.             if(inputStream!=null){  
  13.                 ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  14.                 byte[] buffer = new byte[1024];  
  15.                 int count = 0;  
  16.                 while ((length = inputStream.read(buffer)) != -1) {  
  17.                     baos.write(buffer, 0, length);  
  18.                     count += length;  
  19.                     //这句通知upXXX更新进度  
  20.                     publishProgress((int) ((count / (float) totalLength) * 100));  
  21.                 }  
  22.                 byte[] data=baos.toByteArray();//声明字节数组  
  23.                 downloadImg=BitmapFactory.decodeByteArray(data, 0, data. length);  
  24.                 return "ok";  
  25.             }  
  26.         }  

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

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

[java]  view plain copy
  1. @Override  
  2.     protected void onProgressUpdate(Integer... progress) {  
  3.           super.onProgressUpdate(progress[0]);  
  4.           mBar.setProgress(progress[0]);  
  5.           Log.e("akira",progress[0]+"...");  
  6.     }  

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

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

最后post方法没修改 

3  

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

以下url

https://github.com/daimajia/NumberProgressBar

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

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

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

下面是我的layout代码

[html]  view plain copy
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     xmlns:custom="http://schemas.android.com/apk/res-auto"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     tools:context=".MainActivity"  
  7.     >  
  8.   
  9.     <TextView  
  10.         android:id="@+id/hello"  
  11.         android:text="@string/hello_world" android:layout_width="wrap_content"  
  12.         android:layout_height="wrap_content" />  
  13.   
  14.     <Button  
  15.         android:layout_below="@id/hello"  
  16.         android:id="@+id/downBtn"  
  17.         android:text="down"  
  18.         android:textSize="20sp"  
  19.         android:textColor="@android:color/black"  
  20.         android:layout_width="match_parent"  
  21.         android:layout_height="wrap_content" />  
  22.   
  23.     <ImageView  
  24.         android:layout_centerInParent="true"  
  25.         android:layout_below="@id/downBtn"  
  26.         android:id="@+id/img"  
  27.         android:layout_width="wrap_content"  
  28.         android:layout_height="wrap_content"  
  29.         android:scaleType="fitXY"  
  30.         android:visibility="gone"  
  31.         />  
  32.   
  33.     <com.daimajia.numberprogressbar.NumberProgressBar  
  34.         style="@style/NumberProgressBar_Funny_Orange"  
  35.         android:id="@+id/bar"  
  36.         android:layout_centerInParent="true"  
  37.         android:layout_width="wrap_content"  
  38.         android:layout_height="wrap_content"  
  39.         android:visibility="gone"  
  40.         />  
  41.     <!--<ProgressBar  
  42.         android:id="@+id/bar"  
  43.         android:layout_centerInParent="true"  
  44.         android:layout_width="wrap_content"  
  45.         android:layout_height="wrap_content"  
  46.         android:visibility="gone"  
  47.         />-->  
  48.   
  49. </RelativeLayout>  

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

不行你看

[html]  view plain copy
  1. <style name="NumberProgressBar_Funny_Orange">  
  2.         <item name="android:layout_height">wrap_content</item>  
  3.         <item name="android:layout_width">match_parent</item>  
  4.         <item name="max">100</item>  
  5.         <item name="progress">0</item>  
  6.         <item name="progress_unreached_color">#CCCCCC</item>  
  7.         <item name="progress_reached_color">#FF530D</item>  
  8.         <item name="progress_text_size">10sp</item>  
  9.         <item name="progress_text_color">#FF530D</item>  
  10.         <item name="progress_reached_bar_height">1.5dp</item>  
  11.         <item name="progress_unreached_bar_height">0.75dp</item>  
  12.     </style>  

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

所以直接用就可以了

main代码修改

[java]  view plain copy
  1. public class MainActivity extends Activity {  
  2.     String url ;  
  3.     private  final int  WIFI_STATE_DISABLING = 0 ;//表示停用中。  
  4.     private  final int  WIFI_STATE_DISABLED  = 1//表示不可用。  
  5.     private  final int  WIFI_STATE_ENABLING  = 2//表示启动中。  
  6.     private  final int  WIFI_STATE_ENABLED   = 3//表示准备就绪。  
  7.     private  final int  WIFI_STATE_UNKNOWN   = 4//表示未知状态。  
  8.     private  NetworkInfo mInfo;  
  9.     private ConnectivityManager cManager;  
  10.     private Button downBtn;  
  11.     @Override  
  12.     protected void onCreate(Bundle savedInstanceState) {  
  13.         super.onCreate(savedInstanceState);  
  14.         setContentView(R.layout.activity_main);  
  15.         if(TextUtils.isEmpty(url))  
  16.             url = "http://bbra.cn/Uploadfiles/imgs/20110303/fengjin/015.jpg";  
  17.         final NumberProgressBar bar = (NumberProgressBar) findViewById(R.id.bar);  
  18.         final ImageView img = (ImageView) findViewById(R.id.img);  
  19.         final WifiManager manager = (WifiManager) getSystemService(WIFI_SERVICE);  
  20.         int wifiState =  manager.getWifiState();//wifi状态  
  21.         cManager = (ConnectivityManager)getSystemService(CONNECTIVITY_SERVICE);  
  22.         mInfo =  cManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);  
  23.         downBtn = (Button) findViewById(R.id.downBtn);  
  24.         if (mInfo.isAvailable() && !TextUtils.isEmpty(url)){  
  25.                 downBtn.setClickable(true);  
  26.                 downBtn.setOnClickListener(new View.OnClickListener() {  
  27.                 @Override  
  28.                 public void onClick(View view) {  
  29.                     new ImageDownloadTask(MainActivity.this,img,bar).execute(url);  
  30.   
  31.                 }  
  32.              });  
  33.         }else{  
  34.             downBtn.setClickable(false);  
  35.             downBtn.setOnClickListener(null);  
  36.             Toast.makeText(MainActivity.this,"当前无wifi",Toast.LENGTH_SHORT).show();  
  37.         }  
  38.   
  39.     }  
  40.   
  41.   
  42. }  

ImageDownXXX代码修改

[java]  view plain copy
  1. /** 
  2.  * Created by akira on 2015/1/27. 
  3.  */  
  4. public class ImageDownloadTask extends AsyncTask<String,Integer,String> {  
  5.     private Bitmap downloadImg;  
  6.     private NumberProgressBar mBar;  
  7.     private Context mContext;  
  8.     private ImageView netImageView;  
  9.     private int perPro;//递增的进度  
  10.     public ImageDownloadTask(Context context, ImageView imageView, NumberProgressBar bar){  
  11.         this.mContext = context;  
  12.         this.netImageView = imageView;  
  13.         this.mBar = bar;  
  14.         mBar.incrementProgressBy(perPro);  
  15.     }  
  16.   
  17.     @Override  
  18.     protected void onPreExecute() {  
  19. //        super.onPreExecute();  
  20.         mBar.setVisibility(View.VISIBLE);  
  21.     }  
  22.   
  23.     @Override  
  24.     protected String doInBackground(String... params) {  
  25.         int totalLength;//总共长度  
  26.         URL imageUrl = null;//图片的url  
  27.         int length = -1;  
  28.         InputStream inputStream = null;  
  29.         try {  
  30.             imageUrl = new URL(params[0]);  
  31.             HttpURLConnection connection = (HttpURLConnection) imageUrl.openConnection();  
  32.             connection.setDoInput(true);  
  33.             connection.connect();  
  34.             inputStream =  connection.getInputStream();  
  35.             totalLength = connection.getContentLength();  
  36.             if(inputStream!=null){  
  37.                 ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  38.                 byte[] buffer = new byte[1024];  
  39.                 int count = 0;  
  40.                 while ((length = inputStream.read(buffer)) != -1) {  
  41.                     baos.write(buffer, 0, length);  
  42.                     count += length;  
  43.                     //这句通知upXXX更新进度  
  44.                     publishProgress((int) ((count / (float) totalLength) * 100));  
  45.                 }  
  46.                 byte[] data=baos.toByteArray();//声明字节数组  
  47.                 downloadImg=BitmapFactory.decodeByteArray(data, 0, data. length);  
  48.                 return "ok";  
  49.             }  
  50.         } catch (MalformedURLException e) {  
  51.             e.printStackTrace();  
  52.         } catch (IOException e) {  
  53.             e.printStackTrace();  
  54.         }finally {  
  55.             try {  
  56.                 inputStream.close();  
  57.             } catch (IOException e) {  
  58.                 e.printStackTrace();  
  59.             }  
  60.         }  
  61.   
  62.         return null;  
  63.     }  
  64.   
  65.     @Override  
  66.     protected void onProgressUpdate(Integer... progress) {  
  67.           super.onProgressUpdate(progress[0]);  
  68.           mBar.setProgress(progress[0]);  
  69.           Log.e("akira",progress[0]+"...");  
  70.     }  
  71.   
  72.   
  73.     @Override  
  74.     protected void onPostExecute(String result) {  
  75. //        super.onPostExecute(s);  
  76.          mBar.setVisibility(View.GONE);  
  77.          netImageView.setVisibility(View.VISIBLE);  
  78.          netImageView.setImageBitmap(downloadImg);  
  79.          Toast.makeText(mContext,"加载完毕",Toast.LENGTH_LONG).show();  
  80.     }  
  81. }  
究竟行不行 来运行运行吧



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


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

各位下期再会!

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值