最近再找好用的异步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.javapackage 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); } } } } /* private void showProgress(Object p, String url, boolean show){ if(p != null){ if(p instanceof View){ View pv = (View) p; ProgressBar pbar = null; if(p instanceof ProgressBar){ pbar = (ProgressBar) p; } if(show){ pv.setTag(AQuery.TAG_URL, url); pv.setVisibility(View.VISIBLE); if(pbar != null){ pbar.setProgress(0); pbar.setMax(100); } }else{ Object tag = pv.getTag(AQuery.TAG_URL); if(tag == null || tag.equals(url)){ pv.setTag(AQuery.TAG_URL, null); if(pbar != null && pbar.isIndeterminate()){ pv.setVisibility(View.GONE); } } } }else if(p instanceof Dialog){ Dialog pd = (Dialog) p; AQuery aq = new AQuery(pd.getContext()); if(show){ aq.show(pd); }else{ aq.dismiss(pd); } }else if(p instanceof Activity){ Activity act = (Activity) p;; act.setProgressBarIndeterminateVisibility(show); act.setProgressBarVisibility(show); if(show){ act.setProgress(0); } } } }*/ }//在util包内新增 OnProgressListener.javapackage 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的,支持国产!