您的位置:首页 > 移动开发 > Android开发

技术日报开源项目

2017-03-28 11:28 447 查看
        项目介绍:项目分为资讯和图片和关于三大类,资讯分为github、hacker、SegmentFault、jobBole、技术头条、Android、ios、和all,图片是美女福利图片、并提供下载。

项目已在应用宝上线:地址http://android.myapp.com/myapp/detail.htm?apkName=com.infomation.haiffeng

项目用到的技术框架
1:采用okhttp3+retrofit2+rxjava+rxandroid+hawk+logging搭建的网络模块,支持离线缓存阅读模式。
2:其他第三方:采用picasso作为图片加载,easyrecyclerview、butterknife、bottom-navigation-bar
3:采用的第三方api:http://geekvi.net/
http://gank.io/ 4:根据功能模块分包,采用material design风格设计

效果如图:




1、网络模块,采用的okhttp3+retrofit2封装,是在henlin封装的基础上二次封装,缓存+生命周期。由于是请求不同的Api地址,所以有两个ApiService

public class Api {
private static ApiService SERVICE,SERVICEG;
/**
* 请求超时时间
*/
private static final int DEFAULT_TIMEOUT = 10000;

public static ApiService getDefault() {
if (SERVICE == null) {
//手动创建一个OkHttpClient并设置超时时间
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
httpClientBuilder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
httpClientBuilder.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.HEADERS));
/**
*  拦截器
*/
httpClientBuilder.addNetworkInterceptor(new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
HttpUrl.Builder authorizedUrlBuilder = request.url()
.newBuilder();
//添加统一参数 如手机唯一标识符,token等
//                            .addQueryParameter("key1","value1")
//                            .addQueryParameter("key2", "value2");
Request newRequest = request.newBuilder()
//对所有请求添加请求头
//                            .header("mobileFlag", "adfsaeefe").addHeader("type", "4")
.method(request.method(), request.body())
.url(authorizedUrlBuilder.build())
.build();
return  chain.proceed(newRequest);
}
});
SERVICE = new Retrofit.Builder()
.client(httpClientBuilder.build())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.baseUrl(Url.BASE_URL)
.build().create(ApiService.class);
}
return SERVICE;
}

public static ApiService getGankDefault() {
if (SERVICEG == null) {
//手动创建一个OkHttpClient并设置超时时间
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
httpClientBuilder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
httpClientBuilder.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.HEADERS));
/**
*  拦截器
*/
httpClientBuilder.addNetworkInterceptor(new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
HttpUrl.Builder authorizedUrlBuilder = request.url()
.newBuilder();
//添加统一参数 如手机唯一标识符,token等
//                            .addQueryParameter("key1","value1")
//                            .addQueryParameter("key2", "value2");
Request newRequest = request.newBuilder()
//对所有请求添加请求头
//                            .header("mobileFlag", "adfsaeefe").addHeader("type", "4")
.method(request.method(), request.body())
.url(authorizedUrlBuilder.build())
.build();
return  chain.proceed(newRequest);
}
});
SERVICEG = new Retrofit.Builder()
.client(httpClientBuilder.build())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.baseUrl(Url.GBASE_URL)
.build().create(ApiService.class);
}
return SERVICEG;
}
}
有两个解析器
/**
* geek的api
* @param <T>
* @return
*/
public static <T> Observable.Transformer<HttpResult<T>, T> handleResult(final ActivityLifeCycleEvent event, final PublishSubject<ActivityLifeCycleEvent> lifecycleSubject) {
return new Observable.Transformer<HttpResult<T>, T>() {
@Override
public Observable<T> call(Observable<HttpResult<T>> tObservable) {
Observable<ActivityLifeCycleEvent> compareLifecycleObservable =
lifecycleSubject.takeFirst(new Func1<ActivityLifeCycleEvent, Boolean>() {
@Override
public Boolean call(ActivityLifeCycleEvent activityLifeCycleEvent) {
return activityLifeCycleEvent.equals(event);
}
});
return tObservable.flatMap(new Func1<HttpResult<T>, Observable<T>>() {
@Override
public Observable<T> call(HttpResult<T> result) {
if ("OK".equals(result.getMessage())) {
return createData(result.getData());
} else {
return Observable.error(new ApiException(0));
}
}
}).takeUntil(compareLifecycleObservable).subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).subscribeOn(AndroidSchedulers.mainThread()).observeOn(AndroidSchedulers.mainThread());
}
};
}

/**
* gank.io的api
* @param <T>
* @return
*/
public static <T> Observable.Transformer<GHttpResult<T>, T> handleResultG(final ActivityLifeCycleEvent event, final PublishSubject<ActivityLifeCycleEvent> lifecycleSubject) {
return new Observable.Transformer<GHttpResult<T>, T>() {
@Override
public Observable<T> call(Observable<GHttpResult<T>> tObservable) {
Observable<ActivityLifeCycleEvent> compareLifecycleObservable =
lifecycleSubject.takeFirst(new Func1<ActivityLifeCycleEvent, Boolean>() {
@Override
public Boolean call(ActivityLifeCycleEvent activityLifeCycleEvent) {
return activityLifeCycleEvent.equals(event);
}
});
return tObservable.flatMap(new Func1<GHttpResult<T>, Observable<T>>() {
@Override
public Observable<T> call(GHttpResult<T> result) {
if ("false".equals(result.getError())) {
return createData(result.getResults());
} else {
return Observable.error(new ApiException(0));
}
}
}).takeUntil(compareLifecycleObservable).subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).subscribeOn(AndroidSchedulers.mainThread()).observeOn(AndroidSchedulers.mainThread());
}
};
}
界面主要是bottom-navigation-bar+fragment+easyrecyclerview。

public void initView() {
bottomNavigationBar.setMode(BottomNavigationBar.MODE_SHIFTING);
bottomNavigationBar.setBackgroundStyle(BottomNavigationBar.BACKGROUND_STYLE_RIPPLE);
bottomNavigationBar.addItem(new BottomNavigationItem(R.mipmap.information, "文章").setActiveColorResource(R.color.colorPrimary))
.addItem(new BottomNavigationItem(R.mipmap.tuku, "图库").setActiveColorResource(R.color.colorAccent))
.addItem(new BottomNavigationItem(R.mipmap.about, "关于").setActiveColorResource(R.color.colorJu))
.setFirstSelectedPosition(0)
.initialise();

getFragments();
setDefaultFragment();
bottomNavigationBar.setTabSelectedListener(this);
}

public void getFragments() {
fragments = new ArrayList<>();
InformationFragment informationFragment = new InformationFragment();
GalleryFragment galleryFragment = new GalleryFragment();
AboutFragment aboutFragment = new AboutFragment();
fragments.add(informationFragment);
fragments.add(galleryFragment);
fragments.add(aboutFragment);
}

public void setDefaultFragment() {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction =  fragmentManager.beginTransaction();
transaction.replace(R.id.frame_layout,fragments.get(0));
transaction.commit();
}

@Override
public void onTabSelected(int position) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction =  fragmentManager.beginTransaction();
if (fragments.get(position).isAdded()){
transaction.hide(fragments.get(mLastPosition)).show(fragments.get(position));
}else{
transaction.hide(fragments.get(mLastPosition)).add(R.id.frame_layout,fragments.get(position));
}
transaction.commit();
mLastPosition = position;
}
分享采用的是系统自带的分享
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu,menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.action_share_url:
shareUrl();
break;
}
return super.onOptionsItemSelected(item);
}
public void shareUrl(){
String url = webView.getUrl();
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_TEXT, url);
shareIntent.setType("text/plain");
startActivity(Intent.createChooser(shareIntent, "分享到"));
}
图片下载采用的是picasso
Target target = new Target(){
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {

File imgFile = new File(savePath);
FileOutputStream ostream = null;
try {
ostream = new FileOutputStream(imgFile);
if (savePath.contains(".PNG")|| savePath.contains(".png")){
bitmap.compress(Bitmap.CompressFormat.PNG, 100, ostream);
}else if (savePath.contains(".JPG")|| savePath.contains(".jpg")) {
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, ostream);
}
ostream.close();
} catch (Exception e) {
e.printStackTrace();
}
Toast.makeText(ImgLookActivity.this,"图片下载至:"+ savePath,Toast.LENGTH_SHORT).show();
}

@Override
public void onBitmapFailed(Drawable errorDrawable) {

}

@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {

}
};
Picasso.with(this).load(mData.get(mPosition)).into(target);
以上就是部分源码

github地址:https://github.com/Ahuanghaifeng

欢迎下载使用和star
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息