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

Android assets 的大坑!

  •  
  •   gramyang · 100 天前 · 2532 次点击
    这是一个创建于 100 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    有什么别的解决方案吗?

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

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

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

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

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

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

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

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