開發框架搭建——常用基類的封裝
我們想要開發一款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中,我們主要做了三件事:
- 獲取當前系統使用使用者(有使用者模組的話)
- 定義了一個用於列印log的TAG,以當前類的類名為值
- 定義了一個全域性錯誤異常類,在程式出現異常的時候可以捕獲異常。(異常處理類後面會貼出)
下面再來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中我們做了很多處理:
- 定義了一個AlertDialog,警告對話方塊
- 定義了一個ProgressDialog,進度對話方塊
- 實現了一個判斷使用者是否登入的方法
- 維護了一個活動棧,並且開放了一個退出所有活動的方法
- 定義了抽象四個方法: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