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

Android assets 的大坑!

  •  
  •   gramyang · 5 天前 · 2160 次点击

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

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

    有什么别的解决方案吗?

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

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

    是不是和这个有关呢?
    第 3 条附言  ·  4 天前
    又测试了一下,发现问题了:
    sslContext1 = SSLContext.getInstance("SSLv3");
    这行代码在 Android 里面报空。。。。。

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

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

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

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

    ???
        30
    nicevar   4 天前
    楼主是个大坑,你们都听他瞎扯蛋。。。
        31
    nicevar   4 天前
    我猜测一下可能性,楼主可能启动了一个 remote 的 service,跨进程了,由于知识不足找不到问题所在
        32
    janus77   4 天前
    用 raw 啊 别用 assets
        33
    rigortek   4 天前
    show me you code
    别在这瞎聊,让大家猜来猜去
        34
    hhhsuan   4 天前 via Android
    明明可以读,我一直都是这样做的。
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2694 人在线   最高记录 5043   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 25ms · UTC 12:34 · PVG 20:34 · LAX 05:34 · JFK 08:34
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1