最近再找好用的异步http通信库,在OSC上找到一款功能强大的android轻量级辅助库android query,支持view的绑定,链式调用,http通信,网页或本地图片的异步加载,以及强大的cahe功能,当然还有更多的细节可以到Google Source的页面上查看:https://code.google.com/p/android-query/
但是在异步操作显示进度上有些不完善,例如只支持progressbar的绑定,不能动态获得进度,我觉得在很多场合上动态地获得进度更加灵活,所以在android query的代码上修改了一下,加入了OnProgressListener类,没有用接口是因为不能绑定数据,没有通过继承来绑定数据和调用方法那么方便。
具体修改的代码:
//com.androidquery.util Progress.java
package com.androidquery.util;
import android.app.Activity;
import android.app.ProgressDialog;
import android.view.View;
import android.widget.ProgressBar;
import com.androidquery.AQuery;
public class Progress implements Runnable{
private ProgressBar pb;
private ProgressDialog pd;
private Activity act;
private View view;
private OnProgressListener listener;
private boolean unknown;
private int bytes;
private int current;
private String url;
public Progress(Object p){
if(p instanceof ProgressBar){
pb = (ProgressBar) p;
}else if(p instanceof ProgressDialog){
pd = (ProgressDialog) p;
}else if(p instanceof Activity){
act = (Activity) p;
}else if(p instanceof View){
view = (View) p;
}else if (p instanceof OnProgressListener){
listener = (OnProgressListener) p;
}
}
public void reset(){
if(pb != null){
pb.setProgress(0);
pb.setMax(10000);
}
if(pd != null){
pd.setProgress(0);
pd.setMax(10000);
}
if(act != null){
act.setProgress(0);
}
if(listener != null){
listener.onProgress(unknown, bytes, current);
}
unknown = false;
current = 0;
bytes = 10000;
}
public void setBytes(int bytes){
if(bytes <= 0){
unknown = true;
bytes = 10000;
}
this.bytes = bytes;
if(pb != null){
pb.setProgress(0);
pb.setMax(bytes);
}
if(pd != null){
pd.setProgress(0);
pd.setMax(bytes);
}
if(listener != null) {
listener.onProgress(unknown, bytes, current);
}
}
public void increment(int delta){
if(pb != null){
pb.incrementProgressBy(unknown ? 1 : delta);
}
if(pd != null){
pd.incrementProgressBy(unknown ? 1 : delta);
}
if(act != null){
int p;
if(unknown){
p = current++;
}else{
current+= delta;
p = (10000 * current) / bytes;
}
if(p > 9999){
p = 9999;
}
act.setProgress(p);
}
if(listener != null) {
if(!unknown)
current += delta;
listener.onProgress(unknown, bytes, current);
}
}
public void done(){
if(pb != null){
pb.setProgress(pb.getMax());
}
if(pd != null){
pd.setProgress(pd.getMax());
}
if(act != null){
act.setProgress(9999);
}
if(listener != null) {
listener.onProgress(unknown, bytes, bytes);
}
}
@Override
public void run() {
dismiss(url);
}
public void show(String url){
reset();
if(pd != null){
AQuery aq = new AQuery(pd.getContext());
aq.show(pd);
}
if(act != null){
act.setProgressBarIndeterminateVisibility(true);
act.setProgressBarVisibility(true);
}
if(pb != null){
pb.setTag(AQuery.TAG_URL, url);
pb.setVisibility(View.VISIBLE);
}
if(view != null){
view.setTag(AQuery.TAG_URL, url);
view.setVisibility(View.VISIBLE);
}
}
public void hide(String url){
if(AQUtility.isUIThread()){
dismiss(url);
}else{
this.url = url;
AQUtility.post(this);
}
}
private void dismiss(String url){
if(pd != null){
AQuery aq = new AQuery(pd.getContext());
aq.dismiss(pd);
}
if(act != null){
act.setProgressBarIndeterminateVisibility(false);
act.setProgressBarVisibility(false);
}
if(pb != null){
pb.setTag(AQuery.TAG_URL, url);
pb.setVisibility(View.VISIBLE);
}
View pv = pb;
if(pv == null){
pv = view;
}
if(pv != null){
Object tag = pv.getTag(AQuery.TAG_URL);
if(tag == null || tag.equals(url)){
pv.setTag(AQuery.TAG_URL, null);
if(pb != null && pb.isIndeterminate()){
pv.setVisibility(View.GONE);
}
}
}
}
}
//在util包内新增 OnProgressListener.java
package com.androidquery.util;
public abstract class OnProgressListener {
public abstract void onProgress(boolean unknown, int total_bytes, int current);
}
导出jar后就可以使用了,例如:
class MyOnProgressListener extends OnProgressListener {
private XMLData xd;
public MyOnProgressListener(XMLData _xd) {
xd = _xd;
}
@Override
public void onProgress(boolean unknown, int total_bytes, int current) {
if(!unknown && total_bytes!=0)
xd.downlad_progress = current*100/total_bytes;
else
xd.downlad_progress = 0;
View parent = ((View)xd.getTag(0));
if(parent.getTag() == xd) {
ProgressBar pb = (ProgressBar)parent.findViewById(R.id.ih_progressBar);
pb.setProgress(xd.downlad_progress);
pb.setVisibility(View.VISIBLE);
my_handler.sendMsg(xd);
TextView tv = (TextView)parent.findViewById(R.id.ih_progressBar_text);
tv.setVisibility(View.VISIBLE);
parent.findViewById(R.id.ih_info).setVisibility(View.INVISIBLE);
}
if(MyData.d.get().a_downloadlist != null) {
parent = ((View)xd.getTag(1));
if(parent != null && parent.getTag() == xd) {
ProgressBar pb = (ProgressBar)parent.findViewById(R.id.ih_progressBar);
pb.setProgress(xd.downlad_progress);
pb.setVisibility(View.VISIBLE);
my_handler.sendMsg(xd);
TextView tv = (TextView)parent.findViewById(R.id.ih_progressBar_text);
tv.setVisibility(View.VISIBLE);
parent.findViewById(R.id.ih_info).setVisibility(View.INVISIBLE);
}
}
}
}
android query的其他特性我在这里就不解释了,官网上都有详细说明,之前我也看过国内类似的开源库androidfinal(afinal),虽然某些方面确实方便一些,但是比起android query来说确实有很多地方还需要改进,而且感觉是跟风android query,名字也起得稍微有些太霸气了(并非批评),不过我还是会持续关注afinal的,支持国产!