你們好 我是akira上一節 咱們講到使用AsyncTask 這個類進行異步的下載css
主要是涉及到一些圖片的更新 此次咱們繼續上一個demo的改進 。html
不知道你是否發現一個問題 上一節咱們遺留了兩個bug 1 在無網絡狀況下 點擊會崩java
我們說 軟件開發最忌諱的就是crash 而這個是在bug解決方案中的一級要解決的 因此這個問題android
必須搞定 2 就是咱們會發現進度並未更新 而圖片是顯示完畢了的 3 就是一個擴展 此次我將會帶來git
daimajia的新庫 也是作庫小達人的最新做品 NumberProgressBar的使用。github
1 首先 我們問題一個一個的解決 首先是第一個 點擊會崩潰 那咱們就要清楚 whyapi
也就是爲何點擊會崩潰 解決這個問題的源頭要從原來的代碼看起數組
下面這段代碼緩存
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