1. 程式人生 > >開發框架搭建——常用基類的封裝

開發框架搭建——常用基類的封裝

我們想要開發一款APP,首要工作肯定是先把包結構建好,框架搭建起來,然後把基類封裝,需要用到的第三方庫匯入專案等等一系列工作。今天我們就來說下如何完成這一套流程。
(注:每個人都有自己的程式碼風格,所以不存在哪種好,哪種不好,適合自己就可以了。)

通過本篇文章你可以Get到以下技能點:

1、新建專案的包結構如何搭建;
2、新建專案的常用基類的封裝。

正文

包結構的搭建

提到分包大家肯定都有自己的方式,最常見的就是把activity放到一起、把fragment放到一起等等的。當然我也是這樣分包的(嘿嘿)。下面就是我的分包圖:
分包結構圖

這裡我是用了MVP模式,所以分包裡面有一個mvp,如果看管老爺們不需要mvp就是簡單點,那就把mvp換成去掉,把model、activity、fragment放到外面就可以了。

這裡constants是放常量類,widget放的是自定義view的東西。別的包裡面看包名就可以看出來裡面要放什麼東西,所以這裡也不用過多解釋了。各位看管老爺們看一下就行了。

常用基類的封裝

下面才是本文的重點,常用基類的封裝。我們按照順序來,先從Application開始,廢話不多說先上程式碼:

/**
 * @author: X_Meteor
 * @description: 自定義的BaseApplication
 * @version: V_1.0.0
 * @date: 2017/4/21 16:34
 * @email: [email protected]
 */
public
class BaseApplication extends Application { /** * 維護一個全域性的context物件 */ public Context context; /** * 用於存放當前使用者(如果有的話) */ // private static UserInfo currentUser; //單例模式 private static BaseApplication myApplication = null; public static BaseApplication getInstance
() { return myApplication; } /** * 獲取當前的使用者物件 * * @param currentUser */ // public UserInfo getCurrentUser() { // UserInfo user = currentUser; // if (user != null) { // return user; // } // return null; // } /** * 設定當前的使用者物件 * */ // public void setCurrentUser(UserInfo currentUser) { // this.currentUser = currentUser; // } /** * 定義一個標記 */ private static String TAG; @Override public void onCreate() { super.onCreate(); //把TAG定義為當前類的類名 TAG = this.getClass().getSimpleName(); //由於Application類本身已經單例,所以直接按以下處理即可。 myApplication = this; context = getApplicationContext(); //全域性異常處理 if(Constants.isCollectException){ CrashHandlerUtils crashHandler = CrashHandlerUtils.getInstance(); crashHandler.init(getApplicationContext()); } } }

可以看到,在BaseApplication中,我們主要做了三件事:

  1. 獲取當前系統使用使用者(有使用者模組的話)
  2. 定義了一個用於列印log的TAG,以當前類的類名為值
  3. 定義了一個全域性錯誤異常類,在程式出現異常的時候可以捕獲異常。(異常處理類後面會貼出)

下面再來BaseActivity:

/**
 * @author: Meteor
 * @description: 所有Activity的基類
 * @version: V 1.0
 * @date: 2016/12/28 0028 15:33
 * @company:
 * @email: [email protected]
 */
public abstract class BaseActivity extends AppCompatActivity {

    //宣告一個構建著物件,用於建立警告對話方塊
    private AlertDialog.Builder builder;
    //用於建立一個進度條對話方塊
    private ProgressDialog dialog;
    //用於列印log
    private final String TAG = "BaseActivity";
    //宣告一個活動管理棧
    private static Stack<Activity> activities = new Stack<>();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //新增活動到活動棧中
        activities.add(this);

        //固定螢幕方向
        this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        //設定在activity啟動的時候輸入法預設不開啟
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

        initRootView();
        ButterKnife.bind(this);

        initView();
        initData();
        initListener();

        //列印當前類名
        String msg = this.getClass().getName();
        LogUtils.print(msg);
    }

    /**
     * 初始化根佈局檔案
     */
    public abstract void initRootView();

    /**
     * 初始化控制元件
     */
    public abstract void initView();

    /**
     * 初始化資料
     */
    public abstract void initData();

    /**
     * 初始化介面
     */
    public abstract void initListener();

    /**
     * 實現沉浸式通知欄,使通知欄和APP的標題顏色一樣
     */
    protected void immersiveNotification() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            //導航欄透明
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            //底部虛擬按鈕透明
//            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }
    }

    /**
     * 顯示一個警告對話方塊,無按鈕,需要自己設定
     *
     * @param title 標題
     * @param msg   內容
     * @param flag  是否可以取消
     * @return
     */
    protected AlertDialog.Builder showAlertDialog(String title, String msg, boolean flag) {
        if (builder == null) {
            //建立一個構建者物件
            builder = new AlertDialog.Builder(this);
            builder.setTitle(title).setMessage(msg).setCancelable(flag);
        }
        return builder;
    }

    /**
     * 功能:取消警告對話方塊
     */
    protected void dismissAlertDialog(android.app.AlertDialog alertDialog) {
        if (alertDialog != null) {
            //取消警告對話方塊
            alertDialog.dismiss();
        }
    }

    /**
     * 功能 :顯示一個進度條對話方塊
     */
    protected void showProcessDialog(String title, String msg, boolean falg) {
        if (dialog == null) {
            dialog = new ProgressDialog(this);
        }
        dialog.setTitle(title);
        dialog.setMessage(msg);
        dialog.setCancelable(falg);
        dialog.show();
    }

    /**
     * 功能 :取消一個進度條對話方塊
     */
    protected void dismissProcessDialog() {
        if (dialog != null) {
            dialog.dismiss();
        }
    }

    /**
     * 判斷使用者是否登陸過
     *
     * @return true 為登陸成功 false 為沒有登陸過
     */
    protected boolean isLogin() {
    //這裡面做你自己的邏輯處理
        return true;
    }

    /**
     * 退出所有活動並且退出當前應用
     */
    public static void exitApplication() {
        for (Activity activity : activities) {
            if (activity != null) {
                activity.finish();
            }
        }
        System.exit(0);
        android.os.Process.killProcess(android.os.Process.myPid());
    }
}

可以看到,在BaseActivity中我們做了很多處理:

  1. 定義了一個AlertDialog,警告對話方塊
  2. 定義了一個ProgressDialog,進度對話方塊
  3. 實現了一個判斷使用者是否登入的方法
  4. 維護了一個活動棧,並且開放了一個退出所有活動的方法
  5. 定義了抽象四個方法:initRootVeiw();initView;initData();initListener。
    (注:這裡的initRootView是為了使用butterknife專門定義的,我們需要在整合的子類中把setContentView放入其中)

具體可以看程式碼:BaseActivity的onCreate()

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //新增活動到活動棧中
        activities.add(this);

        //固定螢幕方向
        this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        //設定在activity啟動的時候輸入法預設不開啟
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

        initRootView();
        //加入ButterKnife註解框架
        ButterKnife.bind(this);

        initView();
        initData();
        initListener();

        //列印當前類名
        String msg = this.getClass().getName();
        LogUtils.print(msg);
    }

繼承的子類,MainActivity:

public class MainActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public void initRootView() {
        setContentView(R.layout.activity_main);
    }

    @Override
    public void initView() {

    }

    @Override
    public void initData() {

    }

    @Override
    public void initListener() {

    }
}

下面再來BaseFragment:

/**
 * @author: Meteor
 * @description: 所有Fragment的基類
 * @version:
 * @date: 2016/12/28 0028 16:16
 * @company:
 * @email: [email protected]
 */
public abstract class BaseFragment extends Fragment {

    //定義一個用於重複View的回收池
    private View contentView = null;

    /**
     * Fragment當前狀態是否可見
     */
    protected boolean isVisible;
    private AlertDialog.Builder builder;
    private AlertDialog alertDialog;
    private ProgressDialog dialog;
    //用於Butterknife 的繫結
    Unbinder unbinder;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if (contentView == null) {//判斷回收池是否為空
            contentView = initLayout(inflater, container, false);
            unbinder = ButterKnife.bind(this, contentView);
        }
        if (contentView != null) {
            unbinder = ButterKnife.bind(this, contentView);
            return contentView;
        }
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    /**
     * 初始化Fragment的佈局,當要建立試圖時候呼叫
     *
     * @param inflater 佈局填充器
     * @param container ViewGroup
     * @param b     標記
     * @return view 返回檢視
     */
    protected abstract View initLayout(LayoutInflater inflater, ViewGroup container, boolean b);

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        //初始化資料
        initData(savedInstanceState);
    }

    /**
     * 初始化資料,當ViewCreate被建立時呼叫此方法
     * @param savedInstanceState
     */
    protected abstract void initData(Bundle savedInstanceState);

    @Override
    public final void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);

        if (getUserVisibleHint()) {
            isVisible = true;
            onVisible();
        } else {
            isVisible = false;
            onInvisible();
        }
    }

    /**
     * 可見
     */
    protected void onVisible() {
        lazyLoad();
    }

    /**
     * 不可見
     */
    protected void onInvisible() {

    }

    /**
     * 延遲載入
     * 子類必須重寫此方法
     */
    protected abstract void lazyLoad();

    @Override
    public final void onDestroyView() {
        //移除當前檢視,防止重複載入相同檢視使得程式閃退
        ((ViewGroup) contentView.getParent()).removeView(contentView);
        super.onDestroyView();
        unbinder.unbind();
    }

    /**
     * 判斷使用者是否登陸過
     *
     * @return true 為登陸成功 false 為沒有登陸過
     */
    protected boolean isLogin() {
        return false;
    }

    /**
     *  功能 :顯示一個警告對話方塊
     */
    protected void showAlertDialog(String title,String text){
        if (builder==null){
            //建立一個構建者物件
            builder = new AlertDialog.Builder(getContext());
            builder.setTitle(title).setMessage(text).setCancelable(false);
            builder.setPositiveButton("設定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    //跳轉到系統網路設定
                    Intent intent = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
                    startActivity(intent);
                }
            }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    //退出虛擬機器
                    System.exit(0);
                }
            });
        }
        alertDialog = builder.show();
    }

    /**
     * 功能:取消警告對話方塊
     */
    protected void dismissAlertDialog(){
        if (alertDialog!=null){
            //取消警告對話方塊
            alertDialog.dismiss();
        }
    }
    /**
     * 功能 :顯示一個進度條對話方塊
     */
    protected void showProcessDialog(String title,String msg,boolean falg){
        if(dialog==null){
            dialog = new ProgressDialog(getContext());
        }
        dialog.setTitle(title);
        dialog.setMessage(msg);
        dialog.setCancelable(falg);
        dialog.show();
    }

    /**
     * 功能 :取消一個進度條對話方塊
     */
    protected void dismissProcessDialog(){
        if(dialog!=null){
            dialog.dismiss();
        }
    }

    public interface BackHandledInterface {
        public abstract void setSelectedFragment(BaseFragment selectedFragment);
    }
}

這裡除了跟BaseActivity 的相似的顯示對話方塊外,主要多個懶載入方法,關於懶載入的知識,看官老爺們可以自行百度這裡不過多解釋。

子類繼承使用如下:

/**
 * @author: X_Meteor
 * @description: 類描述
 * @version: V_1.0.0
 * @date: 2017/4/22 16:37
 * @email: [email protected]
 */
public class homeFragment extends BaseFragment {
    @Override
    protected View initLayout(LayoutInflater inflater, ViewGroup container, boolean b) {
        View rootView = inflater.inflate(R.layout.activity_main, null);
        return rootView;
    }

    @Override
    protected void initData(Bundle savedInstanceState) {

    }

    @Override
    protected void lazyLoad() {

    }
}

到這裡最常用的基類就封裝完畢了,當然還是那句話,沒有最好的只有最合適的自己的。專案已經上傳 地址如下:
Demo

今天的內容就到此結束了,後面我會寫一下rxjava2 + retrofit2 的網路請求框架的簡單封裝。歡迎大家共同探討學習。

相關推薦

開發框架搭建——常用封裝

我們想要開發一款APP,首要工作肯定是先把包結構建好,框架搭建起來,然後把基類封裝,需要用到的第三方庫匯入專案等等一系列工作。今天我們就來說下如何完成這一套流程。 (注:每個人都有自己的程式碼風格,所以不存在哪種好,哪種不好,適合自己就可以了。) 通過本篇文

Android 基於 MVP 框架的下拉重新整理、上拉載入頁面,View和Presenter層封裝

前言 Android 專案開發中經常遇到列表式頁面,並且需要實現下拉重新整理,上拉到底後加載下一頁的功能,這裡結合我們專案正在使用的 MVP 框架,介紹一種基類封裝方案,實現 View、Adapter、資料處理Presenter層的基類封裝,後續繼承這幾個類,

最全面的Java字節byte操作,處理Java基本數據的轉換及進制轉換操作工具,流媒體及java底層開發項目常用工具

進制 string 常用工具類 cat i++ logs 指定位置 tput off 前言:用於處理Java基本數據的轉換及進制轉換操作工具 一、實現功能 1、int預byte互轉 2、int與byte[]互轉 3、short與byte互轉 4、short與byte[]互轉

react後臺開發框架搭建

out blog project Redux 下載 命令行 apple reac cti 最近整理了一下自己在用的react框架,主要涉及到的技術有react react-router redux Es6 webpack less ant-design等技術,可用於快速

ONVIF學習-ONVIF開發框架搭建(C++)

nts red port ice 框架搭建 代碼 nal tails 服務器 第一步、下載gsoap 從gsoap官網(http://www.genivia.com/products.html#notice)下載最新版gsoap(博主用的是gsoap_2.8.45

JAVA-初步認識-常用對象API(集合框架-List常用的特點)

只需要 大小 虛線 版本 技術 鏈接 bubuko 就是 編號 一. 凡是虛線框都是接口,我們真正在使用的時候,用的是接口中的子類, List接口中,有一堆子類,是我們開發中常用的容器。ArrayList,LinkList,Vecter這三個算是開發中比較常用的。 (l

四、spring集成ibatis進行項目中dao層封裝

access cbc seda gets cat resultset 源碼 -- 錯誤   Apache iBatis(現已遷至Google Code下發展,更名為MyBatis)是當前IT項目中使用很廣泛的一個半自動ORM框架,區別於Hibernate之類的全自動框架,i

專案開發(框架搭建)

主體框架選擇的是SSM進行資料庫選擇是MySQL 問題一:為了能夠在mybatis的配置檔案中使用實體類的別名,在對應的Mybatis配置檔案中應該對相應的包進行掃描 在具體的類上進行相關注解. 例如: 配置檔案中 實體類中 Mapper的對映檔案中 問題二

EF6增改刪等常用

using System; using System.Linq; using System.Threading.Tasks; using System.Linq.Expressions; using System.Collections.Generic; using System.Data.Enti

Java基礎之常用

本文主要介紹幾種Java中常用類的應用。 一、System類 從API當中我們可以看出,public final class System exends Object。System類包含一些有用的欄位和方法。這些欄位和類都被static修飾了,說明他們都不能被例項化。 在System類提

Hybrid開發框架搭建(一)PhoneGap簡介

本系列部落格將介紹採用PhoneGap、Backbone、Seajs、Ratchet和SPM等js庫或工具搭建一個Web主體型的Hybrid模式的移動應用開發框架。   Phonegap是一款開源的開發框架,旨在讓開發者使用HTML、Javascript、CSS等Web&nb

Dialog封裝-----自定義dialog

 該封裝類用於dialog中有比較多的業務邏輯 import android.app.Dialog; import android.content.Context; import android.os.Bundle; import android.support.annotatio

mongodb封裝例項

mongodb的基類 1 <?php 2 3 namespace BI\Service\MongoDB; 4 5 use MongoDB\Driver\BulkWrite; 6 use MongoDB\Driver\Exception\Exception; 7 u

微信小程式開發框架搭建

使用開發工具的正確姿勢 微信提供的開發工具的編輯功能不是一般的水,寫程式碼肯定不能用它,否則就是浪費生命.不說別的,連自動儲存都沒有,第一次寫時寫了一個多小時,後面下班直接關掉,也不彈出提示說沒儲存.然後第二天過來,寫的程式碼全沒了!!! 頓時感到巨坑無比.這

react + redux 開發框架搭建 超詳細

最近週末有時間,想把加入前端一來一年時間對於react以及redux的理解記錄下來,沒有什麼比一個產品更有說服力,在這裡搭建一個簡單的框架,供剛加入前端準備學習react的小白作為入門學習。 專案程式碼,稍後會有升級。 首先使用create-react-ap

最簡單的混合APP開發框架——搭建你的第一個Ionic應用(一)

上次寫了一篇關於Ionic3的文章,但是對於從來沒有接觸過Ionic的開發者來說,可能不是太友好。為了讓更多的人瞭解這個非常好的混合應用開發框架,今天這篇文章主要介紹如何從零用最快的時間做一個Ionic APP。 一)為什麼是Ionic? 如果你以前從來沒有

Spring4.X + Spring MVC + Mybatis3 零配置應用開發框架搭建詳解 (3)

Spring4.X + Spring MVC + Mybatis3 零配置應用開發框架搭建詳解(3) - 實現最基本的登入處理 1. 基本架構:         基礎框架搭建完成後,我們開始進行Spring + SpringMVC + Mybatis的整合,來完成登入功能的

Java常用工具封裝——Base64 編碼和解碼

Base64 編碼和解碼工具類,供參考。 import java.io.*; /** * Base64 編碼和解碼。 * * @author jiangshuai * @date 2016年10月03日 */ public class Base64 { p

Java常用工具封裝——String操作工具

專案中經常需要用到String的一些操作,結合看到的一些前人的工具類抽取,編寫了如下針對String的常用操作的工具類,供大家參考。 package com.mkyong.common; import java.util.ArrayList; import

Android設計模式之Activity封裝

設計模式之Activity基類封裝 概述 為什麼要使用設計模式 模板設計模式的介紹 Activity的與模板設計模式之間的關係 總結 概述 說到設計模式,反正只要做過開發的就能說出一大堆設計模式,像最常用的單例設計模式、工廠設計模式、MV