app框架总结

 代码强迫症晚期患者,碰到新鲜的,觉得确实比自己写的好的,就会把自己的代码全改了,虽然碰到各种各样的坑,但是过程是很爽很爽的,极大的满足感。同时公开了很多公共依赖库,新开发的项目只需要添加一行依赖就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的实现主题的切换是很麻烦的,尤其加上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://sd:dad/aasdfas/")
                            .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可以同时公用所有公共资源类

五。mosby自定义的mvp框架+kotlin的主业务代码+java的自定义控件和工具非业务的代码

猜你喜欢

转载自blog.csdn.net/qq_36017059/article/details/79208053