0%

前言:因为公司氛围没有用,一直很火的mvp模式像鬼一样听说过没见过,今天闲来无事了解一下,发现由普通的MVC改起来还是挺行云流水的,但像有些弹窗不知道写在P层还是V层
关于MVP的概念我就不详细说了,记住关键的一点就是将view与逻辑分离
在谷歌推荐写法下,M层被弱化,数据处理放在了P层
####1.定义一个P接口

1
2
3
public interface BasePresenter {
boolean something();
}

####2.定义一个V接口

1
2
3
public interface BaseView<P extends BasePresenter> {
void setPresenter(P presenter);
}

####3.定义一个合约类管理上述两个接口,Presenter用于定义界面的逻辑与数据,View 用于定义对应的界面显示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class DateRecordContract {
interface Presenter extends BasePresenter {
//获取今日数据
void getTodayData();
//获取所有数据
void getAllData();
//检查数据是否有效
void checkData();
//插入一条数据
void insertDateBean();
//开始计时
void startTiming();
}

interface View extends BaseView<Presenter> {
//显示计时界面
void startAnim();
//刷新界面
void refreshUI(List<DateRecordBean> data);
//停止计时界面
void stopAnim();
//刷新一个界面
void refreshOneDate(DateRecordBean bean);
//保存输入的文本
void saveInputtext(String str);
//获得当前的文本
String getCurrenttext();
//隐藏输入法
void hideInput();
}


}

####4.定义一个P层实现类,最好放在上面的接口同一个包下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public class DateRecordPresenterImpl implements DateRecordContract.Presenter {
private DateRecordContract.View view;
private SharedPreferencesHelper spHelper;

public DateRecordPresenterImpl(DateRecordContract.View view,SharedPreferencesHelper sp) {
this.view = view;
view.setPresenter(this);
spHelper = sp;
}

@Override
public void getTodayData() {
//..处理数据
List<DateRecordBean> list = ...;
//..通知view刷新界面
view.refreshUI(list);
}

@Override
public void getAllData() {
List<DateRecordBean> list = ...;
//
view.refreshUI(list);
}

@Override
public void checkData() {

}

@Override
public void insertDateBean() {
long endTime = System.currentTimeMillis();
DateRecordBean bean = new DateRecordBean();
//..数据处理

//处理完数据后通知view刷新界面
view.refreshOneDate(bean);
}

@Override
public void startTiming() {
view.hideInput();
view.startAnim();

spHelper.put(SharedPreferencesHelper.isStartTime, true);

view.saveInputtext(str);
}
@Override
public boolean something() {
//...自己的处理逻辑
return isStartRecord;
}
}

####5.定义一个View实现类,根据回调显示UI

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class MainActivity extends AppCompatActivity implements DateRecordContract.View {
private DateRecordPresenterImpl presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

presenter = new DateRecordPresenterImpl(this,spHelper);
//通知P层获得今日数据
presenter.getTodayData();
}


@Override
public void refreshUI(List<DateRecordBean> data) {
//显示P层处理好的数据
dapter.addBeans(data);
}
}

以上就是简单的MVP入门,哪里出问题了直接在合约类查看,还是挺方便,也可以把MainActivity改为Fragment实现View,有些疑问是不知道把Dialog放在哪,目前还是放在了Activity中
2018年9月5日08:02:16

前言:项目中被诟病多媒体开机第一次启动很慢,大约3s的黑屏,后续点开启动正常,其中什么原理呢?这就涉及到系统的三种启动模型

1.Cold Start,冷启动

system—>
loding and launching the app
displaying a blank window

createing the app process

process—>
creating the application
launching the main thread
creating the main activity
inflating views
laying out the screen
perfoming the initial draw
main activity place blank window


2.Hot Start,热启动

前台activity因内存不足,被系统销毁重建的过程(重建流程同冷启动)

3.Warm Start

  • 用户点击返回,并重新运行
  • activity不在前台,被系统销毁,由用户主动运行
    可通过onSaveInstance保存状态

4.APP启动慢常见问题

  • Application.onCreate中执行了过重的操作,如I/O操作,频繁创建对象等
  • Activity.onCreate
    布局过于复杂
    Loading and decoding bitmaps
    blocking screen drawing on disk or network I/O
    Rasterinzing vectordrawable objects
    initialztion of other subsystem of the activity

前言:xutils真是一款不错的android开发框架,在使用过程中减少了程序员很多的代码量。不过其中也有一小部分需要注意的地方。其它使用请看xutils3详细用法

1.注解注意事项

不像黄牛刀的注解,xutils的注解是在运行时(ps:我也不懂),用xutils注解点击事件发现,在频繁的切换点击两个button的时候,只会响应一个button的点击,用findviewbyid的方式设置onclicklitsener,就不会有这个bug。

所以我们在用到点击功能的时候,恰当的用一下注解,目前只发现频繁点击会出现问题,不一定其它地方埋着什么。

2.数据库升级

当我们的业务在一天天完善的时候,之前建立的数据库字段可能需要做修改。我们如下配置数据库的代码

    DbManager.DaoConfig daoConfig =newDbManager.DaoConfig()

    .setDbName("myapp.db")//设置数据库名

    xutils.db.setDbDir(newFile("/mnt/sdcard/"))//设置数据库路径,默认存储在app的私有目录

    .setDbVersion(2)//设置数据库的版本号

    .setDbOpenListener(newDbManager.DbOpenListener() {//设置数据库打开的监听

        @Override
        public void onDbOpened(DbManager db) {//开启数据库支持多线程操作,提升性能,对写入加速提升巨大
        db.getDatabase().enableWriteAheadLogging();
}
})
    .setDbUpgradeListener(newDbManager.DbUpgradeListener() {//设置数据库更新的监听

        @Override
        public void onUpgrade(DbManager db,intoldVersion,intnewVersion) {

}

})  .setTableCreateListener(newDbManager.TableCreateListener() {//设置表创建的监听
        @Override
        public void onTableCreated(DbManager db, TableEntity table){
        Log.i("JAVA","onTableCreated:"+ table.getName());
}
});

我们可以在setDbVersion(x)填上任意数字,当然根据我们自己的实际情况

在需要改字段的时候,我们可以填x+n的数字,然后在

.setDbUpgradeListener(newDbManager.DbUpgradeListener() {//设置数据库更新的监听

@Override 
public void onUpgrade(DbManager db,intoldVersion,intnewVersion) {

  //不需要之前的数据

  db.delete(x.class);

  //需要之前的数据

  db.addColumn(x.class,"test");//新增的字段

  db.saveOrUpdate(db.findall());//当前表中有这条isId则更新数据,没有则添加

}

})

感谢android,感谢开源

Android源码编译不同的版本,略微有不同
如下基于9.0

编写app之前,确认编译环境使用的sdk版本,在build.gradle中配置成一样的
删掉不需要用的东西,也许某个虚线下面在编译时就是一个炸弹

一个apk构依赖部分
系统属性/自己项目的module/第三方jar/第三方aar/so库

  • 系统预编译好的属性

    如AndroidX系列,
    implementation ‘androidx.constraintlayout:constraintlayout:1.1.0
    可在编译目录中通过查找对应 name属性
    find prebuilts/sdk/ -name Android.bp|xargs grep "name.*constraintlayout"

mk如下:

1
2
3
4
5
6
7
8
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_USE_AAPT2 := true

...
LOCAL_STATIC_ANDROID_LIBRARIES := \ androidx-constraintlayout_constraintlayout

include $(BUILD_PACKAGE)
  • 依赖自己项目中Module

1.只依赖java文件,即常用的jar包
module中配置Android.bp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
java_library {
name: "constantproxy",

srcs: [
"src/main/java/**/*.java",
],

exclude_srcs: [
],

libs: [
],

static_libs: [
"androidx.media_media", //依赖的系统属性
],

required: [
],

dxflags: [
],

}

app中Android.mk

1
2
3
4
5
6
7
8
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_USE_AAPT2 := true

...
LOCAL_STATIC_JAVA_LIBRARIES := \
constantproxy\

2.既依赖java又依赖res
此种module不需要写mk
在app中引入即可

? 理论上是不是每个module都可以这么写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_USE_AAPT2 := true

LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SRC_FILES += $(call all-java-files-under, yourmodule/src)
LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/src/main/res
LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/yourmodule/src/main/res
#注意yourmodule路径的准确性

LOCAL_AAPT_FLAGS := --auto-add-overlay \
--extra-packages yourmodule包名 \
...

include $(BUILD_PACKAGE)
  • 第三方jar

    在jar的同级目录下新建Androd.bp 如libs/Android.bp
    1
    2
    3
    4
    java_import {
    name: "my_jar",
    jars: ["annotation-1.1.0.jar"],
    }
    如果依赖第三方jar的是库,则在库里面的Android.bp中
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    java_library {
    name: "my_lib_core",

    srcs: [
    "src/main/java/**/*.java",
    ],

    exclude_srcs: [
    ],

    libs: [
    ],

    static_libs: [
    "androidx.appcompat_appcompat","my_jar"
    ],

    required: [
    ],

    dxflags: [
    ],

    }
    如果是自己的项目,则在app中Android.mk
    1
    2
    3
    4
    5
    6
    7
    8
    9
    LOCAL_PATH:= $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_USE_AAPT2 := true
    LOCAL_STATIC_JAVA_LIBRARIES := \
    my_jar \
    ...

    LOCAL_PRIVATE_PLATFORM_APIS := true
    include $(BUILD_PACKAGE)
  • 依赖第三方aar

    在aar同级目录Android.bp中
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    android_library_import {
    name: "navigation-fragment-nodeps",
    aars: ["libs/navigation-fragment-2.3.0-alpha01.aar"],
    sdk_version: "current",
    static_libs: [
    "androidx.fragment_fragment", //navigation-fragment依赖androidx.fragment_fragment
    ],
    }

    android_library {
    name: "androidx.navigation_navigation-fragment",
    sdk_version: "current",
    manifest: "androidx.navigation.fragment/AndroidManifest.xml",
    static_libs: [
    "navigation-fragment-nodeps",
    "androidx.fragment_fragment",
    ],
    java_version: "1.8",
    }
    在Android.mk中
    1
    2
    LOCAL_STATIC_ANDROID_LIBRARIES := \
    androidx.navigation_navigation-fragment
  • so库

    此so库指的是NDK编译出来的so库,libs下直接可用
    需要用到so库的mk里面

1
2
3
4
5
6
7
8
include $(BUILD_PACKAGE)

libs_dir := $(TARGET_OUT)/app/yourapkname/lib/armeabi
$(shell mkdir -p $(libs_dir))
src_files := $(shell ls $(LOCAL_PATH)/libs/armeabi/)
$(foreach file, $(src_files),\
$(shell cp $(LOCAL_PATH)/libs/armeabi/$(file) $(libs_dir)/$(file)))


Android9.0源码中的mk例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_USE_AAPT2 := true
LOCAL_PACKAGE_NAME := APK名字
LOCAL_OVERRIDES_PACKAGES :=
LOCAL_MODULE_TAGS := optional

# can't use LOCAL_SDK_VERSION, otherwise the error will occur like this:
# "(java:sdk) should not link to"
#LOCAL_SDK_VERSION := current
LOCAL_PRIVATE_PLATFORM_APIS := true
LOCAL_PRIVILEGED_MODULE := true
LOCAL_JAVACFLAGS := -Xlint:deprecation -Xlint:unchecked

#LOCAL_PROGUARD_FLAG_FILES := proguard.flags
#LOCAL_JARJAR_RULES := $(LOCAL_PATH)/jarjar-rules.txt

###################################################
# src, res, AndroidManifest.xml ...
###################################################
LOCAL_MANIFEST_FILE := src/main/AndroidManifest.xml
LOCAL_SRC_FILES := $(call all-java-files-under, src/main/java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/src/main/res
LOCAL_ASSET_DIR := $(LOCAL_PATH)/src/main/assets

###################################################
# AS dependencies from androidx or android-support
###################################################
#implementation 'androidx.appcompat:appcompat:1.0.0'
#LOCAL_STATIC_ANDROID_LIBRARIES += androidx.appcompat_appcompat

#implementation 'androidx.constraintlayout:constraintlayout:1.1.0'
#LOCAL_STATIC_ANDROID_LIBRARIES += androidx-constraintlayout_constraintlayout

#implementation 'androidx.recyclerview:recyclerview:1.0.0'
#LOCAL_STATIC_ANDROID_LIBRARIES += androidx.recyclerview_recyclerview

#implementation 'com.google.android.material:material:1.0.0'
#LOCAL_STATIC_ANDROID_LIBRARIES += com.google.android.material_material

###################################################
# custom aar library
###################################################
#LOCAL_STATIC_JAVA_AAR_LIBRARIES += 第三方AAR的别名,如:Demo_xxx-1.0.0
#LOCAL_AAPT_FLAGS += --extra-packages 第三方AAR里面AndroidManifest.xml定义的包名
#LOCAL_RESOURCE_DIR += 如果第三方AAR里面有res编不过的时候可以将res解压出来在此引用,如:$(LOCAL_PATH)/libs/xxx/res
LOCAL_AAPT_FLAGS += --auto-add-overlay

###################################################
# custom jar library
###################################################
#LOCAL_STATIC_JAVA_LIBRARIES += 自定义Module或第三方JAR的别名
#LOCAL_JAVA_LIBRARIES +=

###################################################
# custom jni library
###################################################
LOCAL_JNI_SHARED_LIBRARIES :=

include $(BUILD_PACKAGE)


##############################################################
# Pre-built dependency jars,aars,...
##############################################################
include $(CLEAR_VARS)

#LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES += AAR或JAR别名与文件路径对应关系,如:Demo_xxx-1.0.0:libs/xxx/xxx.aar

include $(BUILD_MULTI_PREBUILT)


##############################################################
# Pre-built dependency jars,aars,...
##############################################################
#prebuilts += xxx:libs/xxx/xxx.aar
#
#define define-prebuilt
# $(eval tw := $(subst :, ,$(strip $(1)))) \
# $(eval include $(CLEAR_VARS)) \
# $(eval LOCAL_MODULE := $(word 1,$(tw))) \
# $(eval LOCAL_MODULE_TAGS := optional) \
# $(eval LOCAL_MODULE_CLASS := JAVA_LIBRARIES) \
# $(eval LOCAL_SRC_FILES := $(word 2,$(tw))) \
# $(eval LOCAL_UNINSTALLABLE_MODULE := true) \
# $(eval LOCAL_SDK_VERSION := system_current) \
# $(eval include $(BUILD_PREBUILT))
#endef
#
#$(foreach p,$(prebuilts),\
# $(call define-prebuilt,$(p)))
#
#prebuilts :=


##############################################################
# find other Android.mk
##############################################################
include $(call all-makefiles-under, $(LOCAL_PATH))

上面的方式都不行的话,直接打包apk编译
xx.apk同级目录Android.mk

1
2
3
4
5
6
7
8
9
10
11
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := weixin
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_PATH := $(TARGET_OUT_APP)
LOCAL_CERTIFICATE := platform
include $(BUILD_PREBUILT)
include $(call all-makefiles-under,$(LOCAL_PATH))

Q1 Conversion to Dalvik format failed: Unable to execute dex: Multiple dex files define L

A1:添加的jar包重复了,可能名字不同,里面的内容相同。这点就做的不好了,提示不出来哪两个文件相同。

Q2 Unknown exception in parseSdkContent. java.lang.StackOverflowError

A2:主工程A Lib (B C) BC之间相互依赖

前言:之前一直用富文本的编辑模式,但是对代码的支持不友好,因此练习了一下markdown,记录下来,对自己有个提醒,也希望能帮助到大家更多技巧


#1.标题

#标题 —-> #标题
##标题 —-> ##标题
###标题 —-> ###标题
####标题 —-> ####标题
#####标题 —-> #####标题
######标题 —-> ######标题
目前支持六种标题大小
#2.引用
输入大于号后跟上文本,就像上面前言中显示的样式.eg: >你好

你好

  • 程序员版本

    ##3.1插入一行代码
    首先我们另起一行,然后在行首连续输入两个”tab”键,跟上代码即可(一定要另起一行) tabtab db.addColumn(x.class,”test”);//新增的字段

    db.addColumn(x.class,”test”);//新增的字段
    ##3.2插入代码块
    连续插入代码,我们需要连续输入三个符号 ```,后面可以跟上语言种类如java,然后代码块输入完毕,换行,在输入三个符号表示代码块结束 键盘esc下面,波浪号的那个键

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //```java(某种编程语言)
    //代码段
    //```
    for (Element e : c) {
    doSomething(e);
    }

    //before JDK1.5
    for (Iterator i = c.iterator(); i.hasNext(); ) {
    doSomething((Element) i.next());
    }

    上面基本上可以满足程序员的基本要求了
    ##4.插入链接
    在简书中的用法是链接语法.png
    DDMS性能调优

故事一

我的下铺是一个五十多岁的中年男子,在公司为我们做饭。每天下班他都会和家里的小朋友视频,看着真是疼爱极了。但是我们每每周末回家的时候他都待在宿舍,一年半载也不回家一次。有天无意中提起他的婚姻,他笑着说:我已经离婚了。很突然,很意外。于是我问到,怎么会呢,你们看起来这么恩爱,这么顾家,什么原因导致的呢?

他说,我那个婆娘,一天到晚拿我跟别个老公比,终于有一天我也成别人老公了。

也许在心中有了比较,彼此在心中的位置就空出来了吧

故事二

恕他人,忍自己

而今常态,忍他人,恕自己

人世间真的有命数吗?

一只猪再怎么拼命挣扎,努力奋斗也逃不过被人宰割的命运吧,可是当初它为什么选择猪圈呢?猪圈里的猪又生小猪猪,让小猪猪以为他们的命运也是如此,吃饱睡,睡饱吃,很安逸的一个圈,殊不知等待他们的都是同一个命运.

逃出这个舒适圈,跑到野地里去,要不了多久就会长出猎人也害怕的獠牙吧,纵使没有獠牙,也有一股难以屈服,拒绝任人宰割的野性吧

每个认为现在安逸环境的人身处的环境,难道不是一个圈吗?待到被命运宰割的时候,怎么嚎叫也无能为力.

可我们有自省和选择的权力,看清身边的处境,待命运之手来临时,狠狠的咬他一口,去他妈的命!!!

老板:不需要在场证明
领导:不在场证明—开会
员工:详述论证一下不在场的证据,以证明这个锅不是你的