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

[置顶] app框架总结

2018-01-30 17:13 295 查看
 代码强迫症晚期患者,碰到新鲜的,觉得确实比自己写的好的,就会把自己的代码全改了,虽然碰到各种各样的坑,但是过程是很爽很爽的,极大的满足感。同时公开了很多公共依赖库,新开发的项目只需要添加一行依赖就ok了,可以快速开发应用
 依赖库

      一。代码框架mvvm+fragmentation:
 1.mvvm的数据绑定各种天马行空的错误,开始的时候真的很头疼,但还是咬牙坚持下来了,mvvm可以通过一行代码控制recylerview填充,刷新
 adapter可以这样写,

@BindingAdapter({"app:functionsf", "app:functionsItem"})
public static void scanAdapter(final RecyclerView recyclerView, final FunctionsFVH scanVH, final ArrayList<FunctionBean> arrayList) {
RecyclerView.Adapter adapter = recyclerView.getAdapter();
if (adapter != null) {
adapter.notifyDataSetChanged();
return;
}

if (scanVH != null && arrayList != null) {
recyclerView.setLayoutManager(new GridLayoutManager(recyclerView.getContext(), 3));
recyclerView.setAdapter(new BaseRecyclerAdapterF<FunctionBean>(arrayList) {
@Override
protected RecyclerView.ViewHolder createNewViewHolder(ViewGroup parent, int viewType) {
ViewDataBinding binding = getBinding(parent, R.layout.f_functions_item);
RecyclerView.ViewHolder viewHolder = new FunctionsFItemVH(binding, scanVH.mCtx);
binding.setVariable(cn.com.reformer.brake.BR.FunctionsFItemVH, viewHolder);
return viewHolder;
}
});
}
} xml文件
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/title_aasdfasf"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:divider="@null"
android:dividerHeight="8dp"
app:functionsItem="@{FunctionsFVH.itmesVHs}"
app:functionsf="@{FunctionsFVH}" />
 viewhodler中的成员变量
public final ObservableArrayList<FunctionBean> itmesVHs = new ObservableArrayList<>();
 通过改变这个成员变量就可以实现adapter的填充,刷新,真tmd英明神武啊

2.framentation是youkey大神的开源框架,通过这个框架完全可以实现单Activity+多Fragment模式,app整体性能很轻,各种跳转很优美,所有也进行了各种各样的踩坑,再完成门禁大师app的时候,实现了一个Activity+多个fragment的框架,其中很多坑比如
 1>activity主题切换:启动主题要更换普通主题的
<!--启动模式-->
<style name="theme_launch" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowFullscreen">true</item>
<item name="android:windowBackground">@drawable/launch_bg</item>
<item name="android:navigationBarColor">@color/colorPrimaryTitle</item>
</style>

<!--主题模式-->
<style name="theme_wangfei" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@color/colorPrimary</item>
<item name="android:navigationBarColor">@color/colorPrimaryTitle</item>
</style> 注意单个activity的
4000
实现主题的切换是很麻烦的,尤其加上fragmentation框架

package com.reformer.util.global;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.view.WindowManager;

import com.baidu.mobstat.StatService;
import com.reformer.util.R;

import me.yokeyword.fragmentation.SupportActivity;
import wangfei.util.global.SpUtil;

public abstract class BaseA extends SupportActivity {
public static BaseA mCtx;//上下文

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initTheme(savedInstanceState);
}

@Override
protected void onResume() {
super.onResume();
StatService.onResume(mCtx);
mCtx = this;
}

@Override
protected void onPause() {
super.onPause();
StatService.onPause(mCtx);
mCtx = null;
SpUtil.putString("welcomeTime", String.valueOf(System.currentTimeMillis()));
}

@Override
protected void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("theme", mCurTheme);
}

public int mCurTheme = 0;

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void initTheme(Bundle savedInstanceState) {
if (savedInstanceState != null) {
initBarState();
int[] themeIds = {R.style.theme_launch, R.style.theme_wangfei, R.style.theme_full_screen};
getWindow().setBackgroundDrawable(null);
mCurTheme = themeIds[savedInstanceState.getInt("theme")];
setTheme(mCurTheme);
reCreateView();
} else {
firstCreate();
switchTheme(1);
}
}

protected abstract void firstCreate();

protected abstract void reCreateView();

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
protected void initBarState() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {//透明状态栏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}

/**
* @param themeID 0启动模式,1.主题模式 ,2.全屏模式
*/
public void switchTheme(final int themeID) {
mCurTheme = themeID;
recreate();
}

}
 实现这个activity要重写两个方法,
public class AllA extends BaseA {

private AllVH allvh;

@Override
protected void firstCreate() {

}

@Override
protected void reCreateView() {
AAllBinding viewDataBinding = DataBindingUtil.setContentView(this, R.layout.a_all);
allvh = new AllVH(this);
viewDataBinding.setAllvh(allvh);

FunctionsF fragment = findFragment(FunctionsF.class);
if (fragment == null)
loadRootFragment(viewDataBinding.flContainer.getId(), FunctionsF.newInstance());

}}
  在第一个firstCreate()的时候调用app的初始化方法,第二个reCreateView()就可以加载界面了,因为直接加载首界面所以还需要判断用户身份,这个时候如果身份不合法需要跳转登陆界面,这个跳转太快了,需要延时500ms(个人建议),否则背景容易重影;fragment创建启动的时候,不能有太多的Obsevable变量刷新界面,否则界面的跳转可能会有抖动的现象
 二。联网框架用的retrofit+rxjava,优点很明显代码逻辑清晰,可异步,快速
public class RetrofitUtils {
// public static final String baseUrl = "http://192111.168111.1111.1111:11111/firmware/";

private static Retrofit retrofit = null;
private static IRetrofitServer iServer;
private static Retrofit retrofit2 = null;
private static IRetrofitServer iServer2;

public static IRetrofitServer getInstance() {
if (retrofit == null) {
synchronized (RetrofitUtils.class) {
if (retrofit == null) {
// OkHttpClient mOkHttpClient=new OkHttpClient.Builder()
// .connectTimeout(HttpConfig.HTTP_TIME, TimeUnit.SECONDS)
// .readTimeout(HttpConfig.HTTP_TIME, TimeUnit.SECONDS)
// .writeTimeout(HttpConfig.HTTP_TIME, TimeUnit.SECONDS)
// .addInterceptor(InterceptorUtil.HeaderInterceptor())
// .addInterceptor(InterceptorUtil.LogInterceptor())//添加日志拦截器
// .build();

retrofit = new Retrofit.Builder()
.baseUrl("http://114.215.171.48:8995/firmware/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())//添加rxjava转换器
.build();
iServer = retrofit.create(IRetrofitServer.class);
}
}
}
return iServer;
}

public static IRetrofitServer getInstance2(final ProgressListener progressListener) {
if (retrofit2 == null) {
synchronized (RetrofitUtils.class) {
if (retrofit2 == null) {
// OkHttpClient mOkHttpClient=new OkHttpClient.Builder()
// .connectTimeout(HttpConfig.HTTP_TIME, TimeUnit.SECONDS)
// .readTimeout(HttpConfig.HTTP_TIME, TimeUnit.SECONDS)
// .writeTimeout(HttpConfig.HTTP_TIME, TimeUnit.SECONDS)
// .addInterceptor(InterceptorUtil.HeaderInterceptor())
// .addInterceptor(InterceptorUtil.LogInterceptor())//添加日志拦截器
// .build();
OkHttpClient client = new OkHttpClient.Builder().addNetworkInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
return response.newBuilder().body(new ProgressResponseBody(response.body(), progressListener)).build();
}
}).build();
retrofit2 = new Retrofit.Builder()
.client(client)
.baseUrl("http://114.215.171.48:8995/firmware/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())//添加rxjava转换器
.build();
iServer2 = retrofit2.create(IRetrofitServer.class);
}
}
}
return iServer2;
}

public interface IRetrofitServer {

//### 1. 获取token
@FormUrlEncoded
@POST("api/emply/Login")
Call<BaseResponse<Token>> getToken(@Field("param") String userPhone);

//### 2. 获取固件设备列表
@FormUrlEncoded
@POST("api/version/date")
Call<BaseResponse<ArrayList<Vertion>>> getDevices(@Field("token") String token, @Field("param") String code);

//### 3.下载固件
@GET
Call<ResponseBody> downFirmware(@Url String fileUrl);

// 如果你下载的文件很大,则使用
@Streaming
@GET
Call<ResponseBody> downloadFileWithDynamicUrlAsync(@Url String fileUrl);
}其实一个实例就行了,有两个是因为有一个是测试下载大文件的,所以分开了
三。整体架构是app module指向多个子module,过个子module共同只想工具类module

 除了app module是apply plugin: 'com.android.application'

 其他的都是apply plugin: 'com.android.library' module之间是单向继承关系,可以保证各个功能子module互不影响,同时公用一个util module可以同时公用所有公共资源类
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐