zm.blog

select * from learn


  • 首页

  • 标签

  • 分类

  • 归档

  • 关于

  • 搜索

高效能人士的七个习惯

发表于 2019-10-18 | 分类于 随笔记 | | 阅读次数:

阅读全文 »

Android混淆使用手册

发表于 2019-10-18 | 分类于 Android , Android Tips | | 阅读次数:

首先,这里说的的混淆其实是包括了代码压缩、代码混淆以及资源压缩等的优化过程。依靠 ProGuard,混淆流程将主项目以及依赖库中未被使用的类、类成员、方法、属性移除,这有助于规避64K方法数的瓶颈;同时,将类、类成员、方法重命名为无意义的简短名称,增加了逆向工程的难度。而依靠 Gradle 的 Android 插件,我们将移除未被使用的资源,可以有效减小 apk 安装包大小。

本文由两部分构成:

  • 第一部分给出混淆的最佳实践,力求让零基础的新手都可以直接使用混淆;
  • 第二部分会介绍一下混淆的整体、自定义混淆规则的语法与实践、自定义资源保持的规则等。

一、Android混淆最佳实践

1. 混淆配置

一般情况下,app module 的 build.gradle 文件默认会有如下结构:

1
2
3
4
5
6
7
8
android {
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

因为开启混淆会使编译时间变长,所以debug模式下不应该开启。我们需要做的是:

  1. 将release下minifyEnabled的值改为true,打开混淆;
  2. 加上shrinkResources true,打开资源压缩。

修改后文件内容如下:

1
2
3
4
5
6
7
8
9
android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
阅读全文 »

Android Activity标签属性

发表于 2019-10-17 | 分类于 Android , Android Tips | | 阅读次数:

Activity 是 Android 系统四大应用组件之一,用户可与 Activity 提供的屏幕进行交互,以执行拨打电话、拍摄照片、发送电子邮件等操作

开发者必须在清单文件中声明要使用的 Activity,这样系统才能访问它。声明方式是在 < application > 元素中添加 < activity > 子元素

1
2
3
4
5
6
7
8
9
10
11
12
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">


<activity android:name=".Example">
</activity>

</application>

可以为< activity >元素设置多个属性值以定义 UI 风格或者运行属性。 android:name 属性是唯一必需的属性,用于指定 Activity 的类名

< activity >包含的属性如下所示

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
<activity android:allowEmbedded=["true" | "false"]
android:allowTaskReparenting=["true" | "false"]
android:alwaysRetainTaskState=["true" | "false"]
android:autoRemoveFromRecents=["true" | "false"]
android:banner="drawable resource"
android:clearTaskOnLaunch=["true" | "false"]
android:configChanges=["mcc", "mnc", "locale",
"touchscreen", "keyboard", "keyboardHidden",
"navigation", "screenLayout", "fontScale",
"uiMode", "orientation", "screenSize",
"smallestScreenSize"]
android:documentLaunchMode=["intoExisting" | "always" |
"none" | "never"]
android:enabled=["true" | "false"]
android:excludeFromRecents=["true" | "false"]
android:exported=["true" | "false"]
android:finishOnTaskLaunch=["true" | "false"]
android:hardwareAccelerated=["true" | "false"]
android:icon="drawable resource"
android:label="string resource"
android:launchMode=["standard" | "singleTop" |
"singleTask" | "singleInstance"]
android:maxRecents="integer"
android:multiprocess=["true" | "false"]
android:name="string"
android:noHistory=["true" | "false"]
android:parentActivityName="string"
android:permission="string"
android:process="string"
android:relinquishTaskIdentity=["true" | "false"]
android:resizeableActivity=["true" | "false"]
android:screenOrientation=["unspecified" | "behind" |
"landscape" | "portrait" |
"reverseLandscape" | "reversePortrait" |
"sensorLandscape" | "sensorPortrait" |
"userLandscape" | "userPortrait" |
"sensor" | "fullSensor" | "nosensor" |
"user" | "fullUser" | "locked"]
android:stateNotNeeded=["true" | "false"]
android:supportsPictureInPicture=["true" | "false"]
android:taskAffinity="string"
android:theme="resource or theme"
android:uiOptions=["none" | "splitActionBarWhenNarrow"]
android:windowSoftInputMode=["stateUnspecified",
"stateUnchanged", "stateHidden",
"stateAlwaysHidden", "stateVisible",
"stateAlwaysVisible", "adjustUnspecified",
"adjustResize", "adjustPan"] >
</activity>
阅读全文 »

关于RecyclerView的解析

发表于 2019-09-29 | 分类于 Android , View | | 阅读次数:

前言

虽然在日常开发中,大伙或多或少都会接触到 RecyclerView,但通常,也就是写写 adapter,用个系统提供的 LayoutManager,写写点击事件,处理处理复杂的 item 布局。

也就是说,大部分场景下,我们其实并不会去接触到 RecyclerView 的大部分其他功能,比如自定义 LayoutManager ,自定义 Item 动画,自定义边界样式,自定义滑动效果,自定义回收策略等等之类的功能。

那么,本篇就专门来试用下这些功能,力求将 RecyclerView 支持的所有功能都试一遍,只有清楚了这个控件都支持哪些功能效果,那么分析起它的架构、原理才会有一个比较清晰的脉络。

目录

由于本篇篇幅特长,特意做了个目录,让大伙对本篇内容先有个大概的了解。

另外,由于有些平台可能不支持 `` 解析,所以建议大伙可借助本篇目录,或平台的目录索引进行快速查阅。

1.LayoutManager

1.1 LinearLayoutManager

  • 基本效果介绍
  • findFirstCompletelyVisibleItemPosition()
  • findFirstVisibleItemPosition()
  • findLastCompletelyVisibleItemPosition()
  • findLastVisibleItemPosition()
  • setRecycleChildrenOnDetach()

1.2 GridLayoutManager

  • 基本效果介绍
  • setSpanSizeLookUp()

1.3 StaggeredGridLayoutManager

  • 基本效果介绍
  • setFullSpan()
  • findXXX() 系列方法介绍

2.ViewHolder

  • getAdapterPosition()
  • getLayoutPosition()
  • setIsRecyclable()

3.LayoutParams

4.Adapter

  • 基本用法介绍
  • onViewRecycled()
  • onViewAttachedFromWindow()
  • onViewDetachedFromWindow()
  • onAttachedToRecyclerView()
  • onDetachedFromRecyclerView()
  • registerAdapterDataObserver()
  • unregisterAdapterDataObserver()

5.RecyclerView

  • addOnItemTouchListener()
  • addOnScrollListener()
  • setHasFixedSize()
  • setLayoutFrozen()
  • setPreserveFocusAfterLayout()
  • findChildViewUnder()
  • findContainingItemView()
  • findContainingViewHolder()
  • findViewHolderXXX()

6.Recycler

  • setItemViewCacheSize()
  • setViewCacheExtension()
  • setRecycledViewPool()
  • setRecyclerListener()

7.ItemAnimator

  • SimpleItemAnimator

  • DefaultItemAnimator

8.ItemDecoration

  • DividerItemDecoration

  • ItemTouchHelper

  • FastScroller

9.OnFlingListener

  • SnapHelper

  • LinearSnapHelper

  • PagerSnapHelper

阅读全文 »

Android判断当前应用是否开启消息通知

发表于 2019-09-28 | 分类于 Android , Android Tips | | 阅读次数:

当APP有推送功能时,需要判断当前app在手机中是否开启了允许消息推送,否则即使添加了推送代码仍然收不到通知

1
2
3
4
5
6
7
8
9
10
private boolean isNotificationEnabled(Context context) {
boolean isOpened = false;
try {
isOpened = NotificationManagerCompat.from(context).areNotificationsEnabled();
} catch (Exception e) {
e.printStackTrace();
isOpened = false;
}
return isOpened;
}

Api24以上,NotificationManagerCompat中提供了areNotificationsEnabled()方法。该方法中已经对API19以下,API19-24,API24以上,这三种情况做了判断。直接使用其返回值即可。

该方法如果返回true表示打开了消息通知,如果返回false则没有打开。没有打开则跳转设置界面。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private void gotoSet() {
Intent intent = new Intent();
if (Build.VERSION.SDK_INT >= 26) {
// android 8.0引导
intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
intent.putExtra("android.provider.extra.APP_PACKAGE", getPackageName());
} else if (Build.VERSION.SDK_INT >= 21) {
// android 5.0-7.0
intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
intent.putExtra("app_package", getPackageName());
intent.putExtra("app_uid", getApplicationInfo().uid);
} else {
// 其他
intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
intent.setData(Uri.fromParts("package", getPackageName(), null));
}
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}

我们可以在Activity的onCreate中进行判断:

1
2
3
4
5
6
//判断该app是否打开了通知,如果没有的话就打开手机设置页面
if (!isNotificationEnabled()) {
gotoSet();
} else {
//当前app允许消息通知
}
阅读全文 »

Android调用系统分享

发表于 2019-09-27 | 分类于 Android , 代码片段 | | 阅读次数:

获取Android系统分享列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public List<AppInfoVo> getShareApps(Context context) {
PackageManager packageManager = context.getPackageManager();
List<AppInfoVo> appInfoVos = new ArrayList<AppInfoVo>();
List<ResolveInfo> resolveInfos = new ArrayList<ResolveInfo>();
Intent intent = new Intent(Intent.ACTION_SEND, null);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setType("*/*");
PackageManager pManager = context.getPackageManager();
resolveInfos = pManager.queryIntentActivities(intent, PackageManager
.COMPONENT_ENABLED_STATE_DEFAULT);
for (int i = 0; i < resolveInfos.size(); i++) {
AppInfoVo appInfoVo = new AppInfoVo();
ResolveInfo resolveInfo = resolveInfos.get(i);
appInfoVo.setAppName(resolveInfo.loadLabel(packageManager).toString());
appInfoVo.setIcon(resolveInfo.loadIcon(packageManager));
appInfoVo.setPackageName(resolveInfo.activityInfo.packageName);
appInfoVo.setLauncherName(resolveInfo.activityInfo.name);
appInfoVos.add(appInfoVo);
}
return appInfoVos;
}
阅读全文 »

大神进阶之路自定义View

发表于 2019-09-20 | 分类于 Android , View | | 阅读次数:

什么是自定义View

定义

在Android系统中,界面中所有能看到的元素都是View。默认情况下,Android系统为开发者提供了很多View,比如用于展示文本信息的TextView,用于展示图片的ImageView等等。但有时,这并不能满足开发者的需求,例如,开发者想要用一个饼状图来展示一组数据,这时如果用系统提供的View就不能实现了,只能通过自定义View来实现。那到底什么是自定义View呢?

自定义View就是通过继承View或者View的子类,并在新的类里面实现相应的处理逻辑(重写相应的方法),以达到自己想要的效果。

继承结构

Android中的所有UI元素都是View的子类:

PS:由于涉及的类太多,如果将所有涉及到的类全部加到类图里面,类图将十分大,所以此处只列出了View的直接子类。

阅读全文 »

从0到1优雅实现沉浸式状态栏

发表于 2019-09-17 | 分类于 Android , Android Tips | | 阅读次数:

ImmersionStatusBar

阅读全文 »

Android对于有时间戳和token验证的网络请求的处理

发表于 2019-09-16 | 分类于 Android , Android Tips | | 阅读次数:

有些项目为了提高安全性,设计接口时增加了时间戳和token效验,如下所示:

阅读全文 »

设计模式二十一之桥接模式

发表于 2019-09-16 | 分类于 Java , 设计模式 | | 阅读次数:

通过理论,代码示例,Android源码来学习桥接模式

介绍

桥接模式(BridgePattern)也称为桥梁模式,是结构型模式之一。在现实生活中大家都知道 ”桥梁“ 是连接河道两岸的主要交通枢纽,简而言之其作用就是连接河的两边,而我们的桥接模式与现实中的情况很相似,也是承担着连接 ”两边“ 的作用,那么具体是哪两边呢?这里先不着急,我们先来看看定义吧。

定义

将抽象部分与实现部分分离,使它们都可以独立地进行变化。

使用场景

从模式的定义中我们大致可以了解到,这里的 ”桥梁“ 的作用其实就是连接 ”抽象部分“ 与 “实现部分”,但是事实上,任何多维度变化类或者说多个树状类之间的耦合都可以使用桥接模式来实现解耦。

UML 类图

阅读全文 »
1…8910…38
ZhangMiao

ZhangMiao

Android/Flutter Developer

379 日志
58 分类
143 标签
RSS
E-Mail QQ Github StackOverflow
友情链接
  • Kaisir
  • Liujianhui
  • Leo
  • Hongyang
  • Liuwangshu
  • Jspang
  • Blankj
  • WuXiaoLong
  • Molunerfinn
  • Ofind
  • Gcssloop
© 2024 ZhangMiao
由 Hexo 强力驱动
|
主题 — NexT.Gemini v5.1.4
本站访客数 人次 本站总访问量 次