对github上别人项目的分析。觉得他框架搭的不错。好好向他学习学习。
https://github.com/spring2613/Daily
项目亮点颇多,自己找了自己觉得不错的点,分析分析。
下面就开始分析一下吧:
Application–>
我分析代码通常从Application开始分析起来,那么就先看看别人的Application怎么做的吧。
清单文件中:
<application
android:name=".App"
android:allowBackup="true"
android:fullBackupContent="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:theme="@style/BaseAppTheme">
</application>
Android application 和 activity 标签详解:http://blog.csdn.net/self_study/article/details/54020909
Application中,也是App
也就是各种初始化。
setupDatabase
SplashActivity–>
清单文件中:
<activity
android:name=".mvp.ui.activities.SplashActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:theme="@style/AppTheme.FullScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
最先启动的Activity配置
关于Intent详解:http://blog.csdn.net/u012637501/article/details/41080891
SplashActivity–>
再来看看这个SplashActivity:
Property Animation
ButterKnife
RxAndroid RxJava
BaseActivity–>
抽象、泛型 :
public abstract class BaseActivity<T extends BasePresenter> extends AppCompatActivity {
protected T mPresenter;
public abstract int getLayoutId();
public abstract void initInjector();
public abstract void initViews();
}
ActivityComponent
DrawerLayout
Toolbar
onNewIntent:
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
}
RefWatcher
NewsActivity–>
DrawerLayout
NavigationView
CoordinatorLayout
AppBarLayout
Toolbar
TabLayout
ViewPager
FloatingActionButton
Snackbar
MVP
Rx
butterknife
dagger
这么多东西结合一起玩。感觉对于现在主流来说是必须会玩的。
BaseFragment–>
跟Activity差不多也是通过泛型跟Presenter关联
NewsListFragment
RecyclerView
SwipeRefreshLayout
Rx
butterknife
dagger
MVP
BaseRecyclerViewAdapter–>
泛型
常用的增删改查
Footer加载更多
setItemAppearAnimation
protected void setItemAppearAnimation(RecyclerView.ViewHolder holder, int position, @AnimRes int type) {
if (position > mLastPosition/* && !isFooterPosition(position)*/) {
Animation animation = AnimationUtils.loadAnimation(holder.itemView.getContext(), type);
holder.itemView.startAnimation(animation);
mLastPosition = position;
}
}
NewsListAdapter–>
onCreateViewHolder
精彩用法:
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, final int viewType) {
View view;
switch (viewType) {
case TYPE_FOOTER:
view = getView(parent, R.layout.item_news_footer);
return new FooterViewHolder(view);
case TYPE_ITEM:
view = getView(parent, R.layout.item_news);
final ItemViewHolder itemViewHolder = new ItemViewHolder(view);
setItemOnClickEvent(itemViewHolder, false);
return itemViewHolder;
case TYPE_PHOTO_ITEM:
view = getView(parent, R.layout.item_news_photo);
final PhotoViewHolder photoItemViewHolder = new PhotoViewHolder(view);
setItemOnClickEvent(photoItemViewHolder, true);
return photoItemViewHolder;
default:
throw new RuntimeException("there is no type that matches the type " +
viewType + " + make sure your using types correctly");
}
}
Glide
Google推荐的图片加载库Glide
多种灵活使用ViewHolder
butterknife
MVP中NewsActivity–>
NewsActivity–>NewsView–>NewsPresenterImpl–>NewsPresenter–>NewsInteractorImpl–>NewsInteractor–>NewsChannelTable–>NewsChannelTableManager
NewsInteractor中用到了Rx的Subscription
public interface NewsInteractor<T> {
Subscription lodeNewsChannels(RequestCallBack<T> callBack);
}
NewsInteractorImpl中用到了Rx的Observable
用到了dagger的@Inject
public class NewsInteractorImpl implements NewsInteractor<List<NewsChannelTable>> {
@Inject
public NewsInteractorImpl() {
}
@Override
public Subscription lodeNewsChannels(final RequestCallBack<List<NewsChannelTable>> callBack) {
return Observable
.create(new Observable.OnSubscribe<List<NewsChannelTable>>() {
@Override
public void call(Subscriber<? super List<NewsChannelTable>> subscriber) {
NewsChannelTableManager.initDB();
subscriber.onNext(NewsChannelTableManager.loadNewsChannelsMine());
subscriber.onCompleted();
}
})
.compose(TransformUtils.<List<NewsChannelTable>>defaultSchedulers())
.subscribe(new Subscriber<List<NewsChannelTable>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
callBack.onError(App.getAppContext().getString(R.string.db_error));
}
@Override
public void onNext(List<NewsChannelTable> newsChannelTables) {
callBack.success(newsChannelTables);
}
}
);
}
}
NewsChannelTable中用到了greendao
NewsChannelTableManager中
repository(仓库)中分为(db)和(network)
NewsChannelTableManager属于从db repository中获取数据
MVP中NewsListFragment–>
NewsListFragment–>NewsListView–>NewsListPresenterImpl–>NewsListPresenter–>NewsListInteractorImpl–>NewsListInteractor–>NewsSummary–>RetrofitManager–>NetUtil
NewsListInteractor中用到了Rx的Observable
public interface NewsListInteractor<T> {
Subscription loadNews(RequestCallBack<T> listener, String type, String id, int startPage);
}
NewsListInteractorImpl(暂时没看懂。)
public class NewsListInteractorImpl implements NewsListInteractor<List<NewsSummary>> {
// private boolean mIsNetError;
@Inject
public NewsListInteractorImpl() {
}
@Override
public Subscription loadNews(final RequestCallBack<List<NewsSummary>> listener, String type,
final String id, int startPage) {
// mIsNetError = false;
// 对API调用了observeOn(MainThread)之后,线程会跑在主线程上,包括onComplete也是,
// unsubscribe也在主线程,然后如果这时候调用call.cancel会导致NetworkOnMainThreadException
// 加一句unsubscribeOn(io)
return RetrofitManager.getInstance(HostType.NETEASE_NEWS_VIDEO).getNewsListObservable(type, id, startPage)
.flatMap(new Func1<Map<String, List<NewsSummary>>, Observable<NewsSummary>>() {
@Override
public Observable<NewsSummary> call(Map<String, List<NewsSummary>> map) {
if (id.endsWith(ApiConstants.HOUSE_ID)) {
// 房产实际上针对地区的它的id与返回key不同
return Observable.from(map.get("北京"));
}
return Observable.from(map.get(id));
}
})
.map(new Func1<NewsSummary, NewsSummary>() {
@Override
public NewsSummary call(NewsSummary newsSummary) {
String ptime = MyUtils.formatDate(newsSummary.getPtime());
newsSummary.setPtime(ptime);
return newsSummary;
}
})
// .toList()
.distinct()
.toSortedList(new Func2<NewsSummary, NewsSummary, Integer>() {
@Override
public Integer call(NewsSummary newsSummary, NewsSummary newsSummary2) {
return newsSummary2.getPtime().compareTo(newsSummary.getPtime());
}
})
.compose(TransformUtils.<List<NewsSummary>>defaultSchedulers())
.subscribe(new Subscriber<List<NewsSummary>>() {
@Override
public void onCompleted() {
KLog.d();
// checkNetState(listener);
}
@Override
public void onError(Throwable e) {
KLog.e(e.toString());
// checkNetState(listener);
// if (!NetUtil.isNetworkAvailable(App.getAppContext())) {
listener.onError(MyUtils.analyzeNetworkError(e));
// }
}
@Override
public void onNext(List<NewsSummary> newsSummaries) {
KLog.d();
listener.success(newsSummaries);
}
});
}
// private void checkNetState(RequestCallBack<List<NewsSummary>> listener) {
// if (!NetUtil.isNetworkAvailable(App.getAppContext())) {
// mIsNetError = true;
// listener.onError(App.getAppContext().getString(R.string.internet_error));
// } else {
// mIsNetError = false;
// }
// }
}
greendao层
DaoMaster
DaoSession
NewsChannelTableDao
common层
ApiConstants
Constants
HostType
LoadNewsType
PhotoRequestType
utils层
widget层
Daily这算是别人做的框架模板,里面有很多知识点。
对于我来说挺陌生的,还得下功夫一个一个学好。
MVP + Rx +Retrofit+OkHttp3 +Dagger入门的一个很好的demo
如果+上模块化,组件化,那些玩意就更厉害了。