library, 即库,可以把一些可重用的功能,做成library,提供给不同的项目集成。网上提供了不少开源的库,如:用于图片加载的universal-image-loader,用于网络数据获取的android-async-http,等等。
这些都是一些大神写的开源的库,我们可以在项目中导入相关的库,就可以在项目中使用库中写好的功能,非常方便。
android有3种不同形式的library:
1、打包成.jar 结尾的文件,这是jar包,只包含了class文件与清单文件 ,不包含资源文件,如图片等所有res中的文件。
如:本项目 DBMovie\app\libs 目录下的:
android-async-http-1.4.5.jar
universal-image-loader-1.9.3.jar
2、项目结构类似于普通android项目的,第三方java类库
如:本项目中的:DBMovie\PullToRefresh
3、AAR(Android Archive)包是一个Android库项目的二进制归档文件,*.aar文件中包含所有资源,class以及res资源文件。
网上有一个文章,是写 arr和jar库的区别的和导入方式,有兴趣也可以看看:http://blog.csdn.net/zxw136511485/article/details/52777286
看回项目中的:
从上图可以看出,这个项目需要用到3个功能:
下拉刷新,网络数据加载,图片加载
这3个功能,当然可以自己写,但网络上已经有大神们集成的library,我们直接调用是最快的。(网上的很多library是开源的,查看别人写的library,也是一种很好的学习方法)
一、图片加载library:universal-image-loader
Image-Loader是一个很强大的图片加载框架,可以对图片进行缓存,图片下载,显示图片。
网上有不少比较详细的,关于这个库的使用方法,我在这里就不一一说明了,可见:
http://www.cnblogs.com/hsx514/p/3460179.html
http://blog.csdn.net/xiaanming/article/details/26810303
下载universal-image-loader的jar包,把它放在:DBMovie\app\libs 目录下。
然后在项目中:
对jar文件 右击,选择Add As Library
然后对话框 点击ok
这样就添加成功了,可以在 app的build.gradle文件中,看到dependencies中添加了这句代码:
compile files('libs/universal-image-loader-1.9.3.jar')
同时,也可以点开jar,看到里面的内容:
在之前创建的MyApplication中,初始化ImageLoader:
public class MyApplication extends Application {
private static MyApplication instance = null;
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
instance = this;
initImageLoader(getApplicationContext());
}
public static MyApplication getInstance() {
return instance;
}
public static void initImageLoader(Context context) {
//缓存目录
File cacheDir = new File(AppConst.cacheDir);
//配置
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
.threadPriority(Thread.NORM_PRIORITY - 2)//设置线程的优先级
.denyCacheImageMultipleSizesInMemory()//当同一个Uri获取不同大小的图片,缓存到内存时,只缓存一个。默认会缓存多个不同的大小的相同图片
.diskCache(new UnlimitedDiscCache(cacheDir))//设置本地缓存目录
.diskCacheSize(50 * 1024 * 1024)//本地缓存大小
.tasksProcessingOrder(QueueProcessingType.FIFO)//设置图片下载和显示的工作队列排序
.build();
//通过配置初始化ImageLoader
ImageLoader.getInstance().init(config);
}
}
使用方法:
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.imgload2)// 加载中显示的图片
.showImageOnFail(R.drawable.imgload2)// 加载失败显示的图片
.cacheInMemory(true)// 缓存保存在内存中
.cacheOnDisk(true)// 缓存保存在硬盘中
.build();
ImageView iv_img = (ImageView)findViewById(R.id.iv_img);
ImageLoader.getInstance().displayImage(imgUrl, iv_img, options);
这样显示一张图片,且把图片缓存在本地,DisplayImageOptions可以有不同的配置,如 显示圆角图片等,我这里就不详细描述了。
二、网络访问library:android-async-http
通常如果我们自己写网络访问类,要写很多内容,配置也复杂,android-async-http开源项目可以让我们轻松的获取网络数据或者向服务器发送数据。
android-async-http的官方地址:http://loopj.com/android-async-http/
android-async-http是一个基于Apache的HttpClient的异步的Android请求框架,网络请求会在另外的线程中执行,得到结果后,会通过AsyncHttpResponseHandler回调进行通知,回调中的方法在主线程中运行(应该说:在哪个线程中发起请求,回调就在哪个线程)
下载jar后,导入方式如之前的Image-Loader,这里就不再次描述了。
见项目中的 ClientApi.java
public class ClientApi {
public static final String Base_Url="https://api.douban.com";//豆瓣api的访问域名
public static final String url_search="/v2/movie/search";//搜索电影
public static final String url_toplist = "/v2/movie/top250";//获取top250的电影列表
public static final String url_hotlist = "/v2/movie/in_theaters";//获取热映的电影
public static final String url_details = "/v2/movie/subject";//获取电影详情
private static AsyncHttpClient client = null;
//单例方法,只在程序中创建一个AsyncHttpClient
public static synchronized AsyncHttpClient getClient() {
if (client == null) {
try {
client = new AsyncHttpClient();
client.setTimeout(20000);
//设置https访问的支持
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
MySSLSocketFactory sf = new MySSLSocketFactory(trustStore);
client.setSSLSocketFactory(sf);
} catch (Exception e) {
}
}
return client;
}
}
使用方式:
(当然android-async-http是一个强大的库,它的可调用方法绝对不只要我这里写出的,具体可以百度一下,网上有很多它的详细解释,我这里只是列出本项目中的使用方式)
//访问url
String visitUrl = ClientApi.Base_Url+ClientApi.url_toplist;
//要携带的参数
RequestParams params = new RequestParams();
params.put("start", rp_start);
params.put("count", rp_limit);
//获取AsyncHttpClient
AsyncHttpClient client1 = ClientApi.getClient();
if(client1!=null) {
//访问,参数1:访问的url,参数2:要携带的参数,参数3:访问结果的回调
client1.post(visitUrl, params, new AsyncHttpResponseHandler() {
public void onFailure(int arg0, Header[] arg1, byte[] arg2,
Throwable paramThrowable) {
//获取数据失败
}
public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
//获取数据成功
String response = null;
if (arg2 != null) {
response = new String(arg2);
}
if (response != null && response.startsWith("\ufeff")) {
response = response.substring(1);
}
}
});
}
这里要注意一点,我这里使用的是1.4.5版本的android-async-http,在使用中,你可能会遇到
import com.loopj.android.http.xxxxx
导入此包相关类时,报错。
原因是:Android 6.0不再支持 Apache HTTP client, 建议使用 HttpURLConnection 代替。如果还想要继续使用 Apache HTTP client 的,请在build.gradle的android块中,添加如下代码:
然后重新同步build.gradle,就可以了。
三、下拉刷新library:Android-PullToRefresh
这个库已经推出很久了的,一个老牌的 下拉刷新,上拉加载更多的library,它的gitHub地址:
https://github.com/chrisbanes/Android-PullToRefresh
它的功能很强大,可以嵌套 ListView / GridView / ScrollView /WebView 等控件 进行下拉刷新。
如,本项目中用到的,就是常见的嵌套 ListView下拉刷新+上拉加载更多
导入方式:
在gitHub中下载它的源代码
下载后,解压文件,得到:
我们要导入文件中的library,打开项目,选择Import Module
选择library的地址,点击Next
就可以了,导入后,你会看到项目中多了一个模块:
然后 右击项目,按如下图选择:
选择app模块,点击Dependencies,点击右边的加号
选择Module dependency
选择刚刚导入的PullToRefresh,点击ok
就可以了。
使用方式:
在layout中,添加控件:
关于控件在layout布局中可以设置什么属性,可见library中的attrs文件:
例如上图,ptrAnimationStyle属性,就可以指定控件刷新时,使用圆形旋转图标rotate,还是箭头图标flip
在代码中:
private void findView(View view) {
PullToRefreshListView pull_lv = (PullToRefreshListView) view.findViewById(R.id.pull_lv);
//设置刷新的模式:常用的有三种
//PullToRefreshBase.Mode.BOTH //上下拉刷新都可以
//PullToRefreshBase.Mode.PULL_FROM_START //只允许下拉刷新
//PullToRefreshBase.Mode.PULL_FROM_END //只允许上拉刷新
pull_lv.setMode(PullToRefreshBase.Mode.BOTH);
//设置Adapter
pull_lv.setAdapter(adapter);
//设置item的点击事件
pull_lv.setOnItemClickListener(itemClickListener);
//设置下拉刷新和上拉加载动作的监听
pull_lv.setOnRefreshListener(orderOnRefresh);
}
private OnRefreshListener2 orderOnRefresh = new OnRefreshListener2() { @Override public void onPullDownToRefresh(PullToRefreshBase refreshView) { //下拉刷新的回调,你在这里可以刷新数据
由于这是一个开源的库,如果你想要更多特别的效果,你甚至可以直接修改library中的代码来实现你的目的。
注意:导入库后,可能会出现 FloatMath这个类报错的情况,这是因为:FloatMath的所有方法都已经从版本23的公共API中删除,官方提示我们可以使用java.lang.Math类来代替使用。
所以,你可以把FloatMath.xxxx的方法改成:(float)Math.xxxx