最近收到本书《Android App开发入门与实战》的一些读者的反馈,希望书籍最后章节的GitHub客户端实战开发环节能否单独拿出来讲解一遍,最好能通过视频形式展示出来。于是这段时间把GitHub客户端开发教程重新整理了一遍,并录制成视频。
这是第6篇,本篇正式进入编码阶段,首先介绍架构和模块的搭建。
本章节建议观看视频讲解。
微信搜索 【国民程序员】,回复 “github”,即可获取本项目源码和后续完整的实战文章教程。
文章目录
-
一、架构
-
- 1. MVVM
-
二、模块
-
- 1. 网络
-
2. 图片
-
3. 数据库
-
4. base
-
5. 数据
-
6. 其它
==============================================================
BaseViewModel是业务VM的基类;
public abstract class BaseViewModel extends AndroidViewModel {
protected Context context;
protected T repository;
public BaseViewModel(@NonNull Application application) {
super(application);
context = application;
repository = TUtil.getInstance(this, 0);
}
}
BaseRepository是业务Model的基类;
public abstract class BaseRepository {
private final String TAG = “BaseRepository”;
protected MutableLiveData<Data> liveDataLogin;
public void login(String authorization) {
… …
}
}
(附)AppRepository处理跟数据相关的业务入口;
==============================================================
public enum RetrofitManager {
INSTANCE;
private final String TAG = “RetrofitManager”;
private HashMap<String, Retrofit> retrofitMap = new HashMap<>();
private void createRetrofit(@NonNull String baseUrl, boolean isJson) {
int timeOut = Constant.HTTP_TIME_OUT;
Cache cache = new Cache(FileUtil.getHttpImageCacheDir(MyApplication.getInstance()),
Constant.HTTP_MAX_CACHE_SIZE);
// Log信息拦截器
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);//这里可以选择拦截级别
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder()
.connectTimeout(timeOut, TimeUnit.MILLISECONDS)
.addInterceptor(loggingInterceptor)
.cache(cache);
if (!StringUtil.isEmpty(App.sAuthorization)) {
okHttpClientBuilder.interceptors().add(0, chain -> {
Request.Builder reqBuilder = chain.request()
.newBuilder().addHeader(“Authorization”, App.sLastLoginUser.getToken());
return chain.proceed(reqBuilder.build());
});
}
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())//定义转化器,用Gson将服务器返回的Json格式解析成实体
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())//关联RxJava
.client(okHttpClientBuilder.build());
if (isJson) {
builder.addConverterFactory(GsonConverterFactory.create());
} else {
builder.addConverterFactory(SimpleXmlConverterFactory.createNonStrict());
}
retrofitMap.put(baseUrl + “-” + isJson, builder.build());
}
/**
-
区分登录态的Retrofit
-
@param baseUrl
-
@param withLogin
-
@return
*/
public Retrofit getRetrofit(@NonNull String baseUrl, boolean withLogin) {
String key = baseUrl + “-” + withLogin;
if (!retrofitMap.containsKey(key)) {
createRetrofit(baseUrl, withLogin);
}
return retrofitMap.get(key);
}
public Retrofit getRetrofit(@NonNull String baseUrl) {
return getRetrofit(baseUrl, true);
}
}
QuickModule:自动切换功能模块的实现方式,以图片模块为例。
QuickModule.imageProcessor().loadNet(url, mImageView);
public class QuickModule {
private static IImageProcessor mIImageProcessor;
private static ImageConfig mImageConfig;
//配置生效
public static void launch() {
//image
if (mIImageProcessor == null) {
mIImageProcessor = new GlideProcessor();
}
mIImageProcessor.init(MyApplication.getInstance(), mImageConfig);
}
//image调用入口
public static T imageProcessor() {
if (mIImageProcessor != null) {
return (T) mIImageProcessor;
}
return (T) new GlideProcessor();
}
//image配置入口
public static ImageConfig configImage() {
return configImage(null);
}
//image配置入口
public static ImageConfig configImage(IImageProcessor processor) {
if (processor == null) {
mImageConfig = new ImageConfig();
}
else {
mIImageProcessor = processor;
mImageConfig = new ImageConfig();
}
return mImageConfig;
}
}
Room主要由三部分组成:Database、Entity、Dao。
public abstract class BaseActivity extends QuickActivity {
//默认不使用自带titlebar
@Override
protected boolean isLoadDefaultTitleBar() {
return false;
}
@Override
protected void getBundleExtras(Bundle extras) {
}
//默认不开启eventbus
@Override
protected boolean isBindEventBus() {
return false;
}
@Override
protected void onEventComing(EventCenter eventCenter) {
}
@Override
protected Intent getGoIntent(Class<?> clazz) {
if (BaseFragment.class.isAssignableFrom(clazz)) {
Intent intent = new Intent(this, FragmentActivity.class);
intent.putExtra(“fragmentName”, clazz.getName());
return intent;
} else {
return super.getGoIntent(clazz);
}
}
}
public abstract class MVVMActivity extends BaseActivity {
protected T mViewModel;
public T getViewModel() {
return mViewModel;
}
public Class getTClass() {
try {
return (Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void initViewsAndEvents(Bundle savedInstanceState) {
if (mViewModel == null) {
Class clazz = getTClass();
if (clazz != null) {
mViewModel = ViewModelProviders.of(this).get(getTClass());
}
}
}
}
状态 + 泛型 + msg
写在最后
最后我想说:对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!
这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
相信它会给大家带来很多收获:
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
泛型 + msg
写在最后
最后我想说:对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!
这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
相信它会给大家带来很多收获:
[外链图片转存中…(img-TPgqWYCF-1714966864385)]
[外链图片转存中…(img-qrXUmXk9-1714966864386)]
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!