Android开发过程中遇到的问题

由于工作原因一直没有时间来维护一个工作笔记,这不是一个好习惯,现在打算在这篇文章里持续更新工作中遇到的一些与Android相关的问题,其中解决问题的方式是我自己工作有效的但不一定是最优解,如有更好的解决方法希望大家指正。

  • 自己开发的多个SDK在集成到同一个项目中时有混淆后包名冲突问题。
    问题原因:由于默认混淆规则会将文件名用abcd...代替所以代码被混淆后很容易出现类似a.a.a.a.class这样的文件并导致冲突。
    解决办法:1.既然是混淆规则导致的就去修改混淆规则,根据项目结构及aar文件对比找出冲突文件进行精减或改变对应的混淆规则,通过如下混淆配置也能一定程度上解决冲突问题:
#不混淆包名,com.*.*是应用包名
-keeppackagenames com.*.*.*

2.默认混淆会导致文件名被abcd替换,可考虑自定义混淆字典来避免混淆后类冲突,自定义混淆字典方法如下:

#自定义混淆字典
-obfuscationdictionary filename .txt
#自定义混淆类名的字典
-classobfuscationdictionary filename .txt
#自定义混淆包名的字典
-packageobfuscationdictionary filename .txt

其中filename.txt是指定的用来生成混淆后的名字的文件。默认情况下,混淆后的名字一般为a、b、c、d以及它们的组合。通过使用-obfuscationdictionary配置的字典文件,可以使用项目指定的字符,如特殊的英文单词、非英文字符等等作为混淆后的类名、成员变量名、方法名。字典文件中的空格,标点符号,重复的词,还有以'#'开头的行都会被忽略。需要注意的是添加了字典并不会显著提高混淆的效果,添加字典有两个作用:一是避免与其他包混淆后重名;二是更不利与阅读;参考混淆字典:

# 使用java中的关键字作字典:避免混淆后与其他包重名,而且混淆之后的代码更加不利于阅读
#
# This obfuscation dictionary contains reserved Java keywords. They can't
# be used in Java source files, but they can be used in compiled class files.
# Note that this hardly improves the obfuscation. Decent decompilers can
# automatically replace reserved keywords, and the effect can fairly simply be
# undone by obfuscating again with simpler names.
# Usage:
#     java -jar proguard.jar ..... -obfuscationdictionary filename.txt
#

do
if
for
int
new
try
byte
case
char
else
goto
long
this
void
break
catch
class
const
final
float
short
super
throw
while
double
import
native
public
return
static
switch
throws
boolean
default
extends
finally
package
private
abstract
continue
strictfp
volatile
interface
protected
transient
implements
instanceof
synchronized

网上有很多变态混淆字典可以自行搜寻。将这个filename .txt混淆字典文件放到项目proguard-rules.pro同级目录下即可。

  • SDK中使用到Webview并开启了多进程,开发者集成后发现Android 9.0及以上版本时自己应用中使用Webview时会异常崩溃,异常如下:
java.lang.RuntimeException
Using WebView from more than one process at once with the same data directory is not supported

问题原因:在 Android 9 中,为改善应用稳定性和数据完整性,应用无法再让多个进程共享一个 WebView 数据目录。如果您的应用必须在多个进程中使用 WebView 实例,则您必须先使用 WebView.setDataDirectorySuffix() 方法为每个进程指定唯一的数据目录后缀,然后再在相应进程中使用 WebView 的给定实例。该方法会将每个进程的网络数据放入应用数据目录内其自己的目录中。
解决办法:为调用WebView的每个进程重新制定其唯一的数据目录。核心代码如下:

public static void configWebViewCacheDirWithAndroidP(Application application) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            String processName = getProcessName(application);
            if (!application.getPackageName().equals(processName)) {
                //判断不等于默认进程名称
                WebView.setDataDirectorySuffix(processName);
            }
        }
    }
private static String getProcessName(Context context) {
        if (context == null) return null;
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) {
            if (processInfo.pid == android.os.Process.myPid()) {
                return processInfo.processName;
            }
        }
        return null;
    }

注意:configWebViewCacheDirWithAndroidP方法需要在进程初始化的时候调用,比如Application的onCreate()中进行调用。

你可能感兴趣的:(Android开发过程中遇到的问题)