zoukankan      html  css  js  c++  java
  • 学习andriod开发之 异步加载图片(二)--- 使用其他进度条

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

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

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

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

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

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

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

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

    下面这段代码

    1
    2
    3
    4
    5
    6
    7
    8
    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的实例化

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

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

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

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

    1
    2
    3
    4
    5
    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的状态 你还需要加上权限

    如下

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


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

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

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

    咱来看看

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


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

    1
    mInfo.isAvailable()


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

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

    要进行并且的判断

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Button downBtn = (Button) findViewById(R.id.downBtn);
            if (mInfo.isAvailable() && !TextUtils.isEmpty(url)){
                    downBtn.setClickable(true);
                    downBtn.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public 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 来看关键代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    int totalLength;//总共长度
            URL imageUrl = null;//图片的url
            int 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了么 那个就是刷新方法

    1
    2
    3
    4
    5
    6
    @Override
        protected 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代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <relativelayout android:layout_height="match_parent" android:layout_width="match_parent" tools:context=".MainActivity" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools">
     
        <textview android:id="@+id/hello" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="@string/hello_world"><button android:id="@+id/downBtn" android:layout_below="@id/hello" android:layout_height="wrap_content" android:layout_width="match_parent" android:text="down" android:textcolor="@android:color/black" android:textsize="20sp">
     
        <imageview android:id="@+id/img" android:layout_below="@id/downBtn" android:layout_centerinparent="true" android:layout_height="wrap_content" android:layout_width="wrap_content" android:scaletype="fitXY" android:visibility="gone">
     
        <com.daimajia.numberprogressbar.numberprogressbar android:id="@+id/bar" android:layout_centerinparent="true" android:layout_height="wrap_content" android:layout_width="wrap_content" android:visibility="gone" style="@style/NumberProgressBar_Funny_Orange">
        <!--<ProgressBar
            android:id=@+id/bar
            android:layout_centerInParent=true
            android:layout_width=wrap_content
            android:layout_height=wrap_content
            android:visibility=gone
            />-->
     
    </com.daimajia.numberprogressbar.numberprogressbar></imageview></button></textview></relativelayout>


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

    不行你看

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <style name="NumberProgressBar_Funny_Orange" type="text/css"><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代码修改

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    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;
        @Override
        protected 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() {
                    @Override
                    public 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代码修改

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    /**
     * 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);
        }
     
        @Override
        protected void onPreExecute() {
    //        super.onPreExecute();
            mBar.setVisibility(View.VISIBLE);
        }
     
        @Override
        protected String doInBackground(String... params) {
            int totalLength;//总共长度
            URL imageUrl = null;//图片的url
            int 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;
        }
     
        @Override
        protected void onProgressUpdate(Integer... progress) {
              super.onProgressUpdate(progress[0]);
              mBar.setProgress(progress[0]);
              Log.e(akira,progress[0]+...);
        }
     
     
        @Override
        protected 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();
        }
    }</string,integer,string>

    究竟行不行 来运行运行吧

    结伴旅游,一个免费的交友网站:www.jieberu.com

    推推族,免费得门票,游景区:www.tuituizu.com

  • 相关阅读:
    UVA 11488 Hyper Prefix Sets (字典树)
    UVALive 3295 Counting Triangles
    POJ 2752 Seek the Name, Seek the Fame (KMP)
    UVA 11584 Partitioning by Palindromes (字符串区间dp)
    UVA 11100 The Trip, 2007 (贪心)
    JXNU暑期选拔赛
    计蒜客---N的-2进制表示
    计蒜客---线段的总长
    计蒜客---最大质因数
    JustOj 2009: P1016 (dp)
  • 原文地址:https://www.cnblogs.com/rabbit-bunny/p/4279712.html
Copyright © 2011-2022 走看看