V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
gramyang
V2EX  ›  Android

Android assets 的大坑!

  •  
  •   gramyang · 2019-05-16 19:30:35 +08:00 · 11043 次点击
    这是一个创建于 2025 天前的主题,其中的信息可能已经有所发展或是发生改变。

    app 用 netty 进行网络请求,传输数据用 SSL 加密,nettysdk 初始化时需要读入 assets 里的 jks 文件。

    结果发现打开 assets 目录只能在 Activity 里!在 Application 里不行,我 tm。。。

    有什么别的解决方案吗?

    第 1 条附言  ·  2019-05-17 08:09:57 +08:00
    留言说可以把 jks 文件持久化成字符串嵌入代码的方案行不通。用 base64 打出来的全是 A,用 String()打出来的是空白。
    第 2 条附言  ·  2019-05-17 10:35:04 +08:00
    有人质疑我的代码问题,代码很多贴出来很麻烦,我口述一下吧。
    1,App 继承 Application 里获取单例:onCreate 里面 app = this。
    2,在工具类里面 App.getApp().getAssets()。就这个地方老是报空指针!无法获取 AssetManager。

    我之前设置过 multiDexEnabled true,因为方法数有 7 万多个,后来又把 multiDexEnabled true 给取消了,但是又没有报过方法数超 64k 了,很奇怪。

    是不是和这个有关呢?
    第 3 条附言  ·  2019-05-17 11:18:37 +08:00
    又测试了一下,发现问题了:
    sslContext1 = SSLContext.getInstance("SSLv3");
    这行代码在 Android 里面报空。。。。。

    是我看错了,assets 可以在 application 里面读取。。。。

    抱歉耽误大家时间了,也感谢大家的热心解答!
    34 条回复    2019-05-17 12:46:39 +08:00
    mouyase
        1
    mouyase  
       2019-05-16 19:50:33 +08:00 via Android
    初始化的时候创建一个没有 ui 的 activity
    pual
        2
    pual  
       2019-05-16 20:10:13 +08:00 via Android
    你直接内嵌到代码中啊
    xiangyuecn
        3
    xiangyuecn  
       2019-05-16 20:14:26 +08:00
    用 zip 读自身 apk 文件内容,不知道可不可行
    gramyang
        4
    gramyang  
    OP
       2019-05-16 20:16:23 +08:00
    @mouyase 研究了一下,activity 也是要执行完 onCreate 之后才能调用 getAssets()。看来也只能这样了。
    gramyang
        5
    gramyang  
    OP
       2019-05-16 20:20:06 +08:00
    @pual 还能把 byte[]内嵌到代码中??
    qianji201712
        6
    qianji201712  
       2019-05-16 20:29:03 +08:00
    简单粗暴点,吧 jks 文件都成的 byte,放到一个类里面,当作一个 byte[] ,哈哈哈,这样就可以了
    gramyang
        7
    gramyang  
    OP
       2019-05-16 20:35:31 +08:00
    @qianji201712 你的意思是,把 jks 文件读成 byte[],再用 utf8 编码成字符串,再放在类里面?
    stdnull
        8
    stdnull  
       2019-05-16 20:59:56 +08:00 via Android
    什么叫打开 assets 目录只能在 activity 里 ? 用 application 的 context 就能打开啊
    cxtrinityy
        9
    cxtrinityy  
       2019-05-16 21:12:20 +08:00
    context 直接 getAssets 就可以啊,我之前还做了后台从 assets 里解压数据库呢
    gramyang
        10
    gramyang  
    OP
       2019-05-16 21:26:26 +08:00
    @stdnull 不能,getAssets 的实现在 ContextThemeWrapper 里面,只能由 Activity 在 onCreate 之后可以打开。
    yippees
        11
    yippees  
       2019-05-16 21:56:14 +08:00
    cpAts2Sd
    yippees
        12
    yippees  
       2019-05-16 22:03:30 +08:00
    错了,快安全的应该还是内置代码··base64 吧
    joyhub2140
        13
    joyhub2140  
       2019-05-16 22:06:31 +08:00 via Android
    都转成 base64,硬编码到 java 代码里,也可以弄到 so 里,通过 jni 读取。
    qianji201712
        14
    qianji201712  
       2019-05-16 22:40:43 +08:00
    @gramyang 对的,他说白了就是一个二进制数据啊,放代码里面也一样的
    ztaober
        15
    ztaober  
       2019-05-16 23:09:40 +08:00
    为什么初始化一定要放在 application 里呢。。。
    MoHen9
        16
    MoHen9  
       2019-05-16 23:47:14 +08:00 via Android
    其实放在 res/raw/下面也可以,一般不是都有个 splash 页面吗?

    我都不知道 assets 目录不能在 application 中读取的问题,明天我去试试。
    pual
        17
    pual  
       2019-05-16 23:54:59 +08:00 via Android
    证书文件内嵌到代码很正常的操作
    james2013
        18
    james2013  
       2019-05-17 00:18:44 +08:00 via Android
    netty 代码包装成单例,延时初始化就可以实现,这样第一次网络请求才会初始化;
    也可以直接放到启动 activity 中
    gramyang
        19
    gramyang  
    OP
       2019-05-17 06:46:28 +08:00
    @MoHen9 这个可以有,我等会试试
    gramyang
        20
    gramyang  
    OP
       2019-05-17 08:24:46 +08:00
    @MoHen9 res/raw/和 asset 是一样的,都是通过 getResources 来读取的,所以都存在 application 里面不能读取的问题。
    kwanzaa
        21
    kwanzaa  
       2019-05-17 08:28:07 +08:00
    你们这么喜欢在 Application.onCreate 里面办事嘛。。。
    MoHen9
        22
    MoHen9  
       2019-05-17 09:23:22 +08:00 via Android
    @gramyang 可以读取,不管是 assets 还是 raw,使用 getAssets().open(“ xxx.jks ”)方法试试,还有,为什么用 Netty 呢?
    cysionliu
        23
    cysionliu  
       2019-05-17 09:23:45 +08:00
    ....怀疑了一下咋会不行呢,花点时间敲个例子,说明 context 直接 getAssets 就可以,难道还有版本问题??

    assets 里有个 hello.txt ,里面有行文字:hello asset

    代码:

    public class MyApp extends Application {

    @Override
    public void onCreate() {
    super.onCreate();
    test();
    }

    private void test() {
    Log.e("flag--", "run(MyApp.java)---->>" + Thread.currentThread().getName());
    try {
    InputStream open = getAssets().open("hello.txt");
    InputStreamReader reader = new InputStreamReader(open);
    BufferedReader bufferedReader = new BufferedReader(reader);
    Log.e("flag--", "run(MyApp.java)---->>" + bufferedReader.readLine());
    } catch (IOException aE) {
    aE.printStackTrace();
    }
    }
    }


    logcat:

    2019-05-17 09:19:54.497 30636-30636/com.haibin.calendarviewproject E/flag--: run(MyApp.java)---->>main
    2019-05-17 09:19:54.498 30636-30636/com.haibin.calendarviewproject E/flag--: run(MyApp.java)---->>hello asset
    olbb
        24
    olbb  
       2019-05-17 09:43:11 +08:00
    试了下可以读啊 不知道楼主为啥读不了
    kile
        25
    kile  
       2019-05-17 10:02:39 +08:00
    你为什么读不了??

    完全不符合多年经验...
    还跑去验证了下
    luwies
        26
    luwies  
       2019-05-17 10:10:04 +08:00
    完全是可以读的
    bkmi
        27
    bkmi  
       2019-05-17 10:10:29 +08:00 via Android
    别到处甩锅了,贴出你的代码来让大伙瞧瞧
    gramyang
        28
    gramyang  
    OP
       2019-05-17 10:27:40 +08:00
    @cysionliu 我也按照你的方法试了一下,在一个空白的 app 里面试了一下,确实可以读。但是我现在的 app 不能读。我这边有一个情况,我之前设定过 multiDexEnabled,最小版本是 21,然后又把 multiDexEnabled 取消了,但是又不提示方法是超过 64k 了。
    会不会是这个原因呢?
    laoyur
        29
    laoyur  
       2019-05-17 10:52:17 +08:00
    > 留言说可以把 jks 文件持久化成字符串嵌入代码的方案行不通。用 base64 打出来的全是 A,用 String()打出来的是空白。

    ???
    nicevar
        30
    nicevar  
       2019-05-17 11:04:23 +08:00
    楼主是个大坑,你们都听他瞎扯蛋。。。
    nicevar
        31
    nicevar  
       2019-05-17 11:10:33 +08:00
    我猜测一下可能性,楼主可能启动了一个 remote 的 service,跨进程了,由于知识不足找不到问题所在
    janus77
        32
    janus77  
       2019-05-17 11:19:45 +08:00
    用 raw 啊 别用 assets
    rigortek
        33
    rigortek  
       2019-05-17 12:40:38 +08:00
    show me you code
    别在这瞎聊,让大家猜来猜去
    hhhsuan
        34
    hhhsuan  
       2019-05-17 12:46:39 +08:00 via Android
    明明可以读,我一直都是这样做的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2626 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 11:02 · PVG 19:02 · LAX 03:02 · JFK 06:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.