1. 程式人生 > >獲取資原始檔,res目錄下的資源時,id報空指標

獲取資原始檔,res目錄下的資源時,id報空指標

在Android開發過程中,我們經常會有這種需求,需要將自己開發一個類庫打包成jar包以供他人(其他人一般指開發者)呼叫,而不是直接打包apk檔案供終端使用者使用。在打包成jar後,你往往會自己先測試一下看jar包能不能直接使用,這時就會常常有如下的幾個問題:

1) Error…..Found duplicate file for APK:res/drawable-xxx/xxx.xx

2) res.Resources$NotFoundException:XXX ID#0x7f090015

3) java.lang.NullPointerException

4) java.lang.NoClassDefFoundError: com.xxx.xxx.R$layout

幾個問題常見的原因是因為資原始檔在作怪。

在第一個問你中,資原始檔被打包進jar,在目標使用project中,也有相同id的資原始檔,引起了衝突,解決方案是別打包資原始檔啦,打包進去也不用的,後面會提到。或許你提到可能改變src project(提供jar包的project)裡面的資源id可以表面上解決這個問題。

不打包資原始檔,但src project中又引用了res的資原始檔,即便你把相應的layout的xml啊String.xml啊等copy到目標project中,也會造成如res.Resources$NotFoundException或者java.lang.NullPointerException,原因是在src中的一些activity呼叫xml中的資源時,控制元件id找不到,例如一個btn = findViewById(R.id.btnXXX);這個btn為空,就會NullPointerException.這個問題原因還是在stackoverflow上有人給出了合理的解釋.

As you want to import the resources,Since Android makes R class automatically with resources files under /res folder, using R class as final static is impossible.in your source code which will be exported in jar file, DON’T USE R variable because it will be replaced with final static memory address in compile time. Instead of using R use method below……

src專案中匯出src資料夾成jar,不包含資原始檔,資原始檔copy到要引用的的其他專案中,但src中不能通過R.id.XXX 獲取xml中的佈局等。因為打包成class的時候,final int 等死了(具體可以看看gen/xxx.xx.R.java),在新專案中是不對應的。解決方案就是用反射的方法.程式碼如下.

public static int getResourseIdByName(String packageName, String className,
            String name)
    {
        Class r = null;
        int id = 0;
        try
        {
            r = Class.forName(packageName + ".R");

            Class[] classes = r.getClasses();
            Class desireClass = null;

            for (int i = 0; i < classes.length; i++)
            {
                if (classes[i].getName().split("\\$")[1].equals(className))
                {
                    desireClass = classes[i];
                    break;
                }
            }

            if (desireClass != null)
                id = desireClass.getField(name).getInt(desireClass);
        } catch (ClassNotFoundException e)
        {
            e.printStackTrace();
        } catch (IllegalArgumentException e)
        {
            e.printStackTrace();
        } catch (SecurityException e)
        {
            e.printStackTrace();
        } catch (IllegalAccessException e)
        {
            e.printStackTrace();
        } catch (NoSuchFieldException e)
        {
            e.printStackTrace();
        }

        return id;

    }

然後利用int id = getResourceIdByName(context.getPackageName(), “layout”, “main”);獲取layout資料夾下main.xml的配置layout,通過int id = getResourceIdByName(context.getPackageName(), “string”, “text1″);獲取string.xml下key為text1的字串,通過int id = getResourceIdByName(context.getPackageName(), “id”, “btn”)獲得id為btn的控制元件等。這個程式碼利用反射執行時找的。
當然具體應用過程中你可以根據上面的這個方法重構一下去掉迴圈找配置而修改成單獨的一些id(key),dimen(key),color(key)之類的方法.這裡就不便(工作需要)將原始碼給出當然也沒必要給出了.

網上說使用library方法載入資原始檔可以解決,即將src project作為library,目標project引用src project.然後說這個方法解決了通過R.XX.XX獲取資源的問題,但還有一個問題是不可能把這個原始碼釋出出去讓其他人使用。我試了試,在我的專案中貌似通過R.XX.XX獲取的控制元件仍然為null,讓人會報空指標異常。

但這個給我提供了一個思路解決了一個比較方便的提供SDK的方式。因為上面的提到的那種需要手動copy layout等xml檔案.如果利用library的話可以避免copy這個操作。具體方案就是,同樣src project打包成lib.jar,然後自己手動建一個library project作為中間project,這個project新增lib.jar並將相應的xml檔案copy到此project.如下圖中的nebula_sdk,然後再發布nebula_sdk這個專案給其他人用,這樣既滿足了功能需求同樣也使程式碼不易洩漏(打包過程仍然可以使用一定的程式碼混淆技術).


相關推薦

獲取原始檔res目錄資源id指標

在Android開發過程中,我們經常會有這種需求,需要將自己開發一個類庫打包成jar包以供他人(其他人一般指開發者)呼叫,而不是直接打包apk檔案供終端使用者使用。在打包成jar後,你往往會自己先測試一下看jar包能不能直接使用,這時就會常常有如下的幾個問題: 1) E

Android_Android工程res目錄原始檔夾螢幕適配

  特殊說明:關於螢幕大小size相關的屬性不在步驟1的過濾清除條件裡(dpi屬性和screen size屬性): 1) 對於dpi屬性系統的選擇方法是"best match"---即如果沒有找到準確的屬性,可以接著尋找最接近的屬性資料夾。例如:我的g7手機,應該是values-hdpi,但如果沒有value

Nginx配置https的wordpress站點wp-content目錄資源404解決方案

pem list log 解決方案 content wordpress timeout nginx span wordpress 下配置 ssl證書, server { listen 443; server_name demo

CommonUtil:常用的工具類eg. 獲取原始檔

/** * 常用的工具類 */ public class CommonUtil { /** * 獲取 string 資原始檔 * @param resId *

C# 獲取原始檔中的DLL呼叫DLL中的方法

轉自:http://blog.163.com/[email protected]/blog/static/16920433220127193511096/ usingSystem;usingSystem.Collections.Generic;usingSyst

maven項目中lib目錄有自己私有的包則需要配置一下代碼然後進行打包

target class int art onf 目錄 otc pac lib <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>ma

Android開發之assets目錄資源使用總結

[] != 大致 pac 模式 uri bsp 文件夾 block 預前知識: Android資源文件分類: Android資源文件大致可以分為兩種: 第一種是res目錄下存放的可編譯的資源文件: 這種資源文件系統會在R

PHP -- 遍歷出目錄所有檔案及演算法優化

在想解決這個問題的時候,我也查找了很多資料。推薦給大家我個人覺得比較好的一篇:PHP遍歷檔案目錄 文中第四個演算法可以遍歷出文件夾下的所有檔案,程式碼如下: $dir = 'E:\phpStudy\PHPTutorial\WWW'; echo '<pre>'; functio

Android jar包裡面有assets目錄有檔案APP的assets裡面也有檔案如何讀呢?

jar 包中可以寫 assets資料夾, APP裡面同時也可以寫assets,但是隻要assets下面的檔案不同名就可以了,忒棒 !!! 如果assets目錄下有檔案的,

關於ESAPI獲取原始檔問題

近期專案中需要使用到元件包ESAPI(ESAPI是owasp提供的一套API級別的web應用解決方案),其官方網站為:https://www.owasp.org/, 有興趣的小夥伴可以瞭解一下。此處不是本文重點,本文重點記錄一下使用此元件時遇到的資源載入問題。 引入jar <!

PHP獲取單選拉列表多選拉列表單選框複選框內的值

PHP獲取單選下拉列表,多選下拉列表,單選框,複選框內的值,此例將當前頁作為提交資料的頁面。 <form action=" " method="post" accept-charset="utf-8"> <!--單選下拉 學歷--> <selec

zabbix自定義指令碼監測windows伺服器指定目錄檔案數量並設定告警及圖形

一、新增自定義監控引數 1、在agent端修改配置檔案允許自定義監控引數 UnsafeUserParameters=1 2、新增自定義監控引數 UserParameter=count.files,dir "f:/test/"|find /C ".Z" 相關DOS命令介紹

jar包獲取原始檔

背景 寫的一個spring boot專案打成jar包部署執行下,打成jar包,提示找不到資原始檔,如下圖:  直接通過idea是可以執行的,但打成jar包後提示找不到資原始檔,簡單查閱後瞭解到是因為jar包在讀取檔案的方式不一致導致的   問題分析 先定位到哪行程式碼出錯,如

Android Uri獲取原始檔(多種方式)

在Android中少不了去獲取資原始檔,在Android裡封裝了幾種獲取固定Resource檔案的方式,今天不講這個。 如果你要獲取資原始檔夾raw目錄下的視訊檔案,那你會怎麼做?  這時候Uri就排上用場了   我在這先設個疑問,通過Uri去拿raw資料夾下的m

ejabberd叢集失敗log目錄產生 .dump檔案

報錯檔案: 報錯資訊如下: =erl_crash_dump:0.3 Sun May 13 16:40:25 2018 Slogan: Kernel pid terminated (application_controller) ({application_

錯誤解決:當前目錄有so提示 error while loading shared libraries

  真是讓人莫名其妙……   ldd檢視 ldd gh_main linux-vdso.so.1 => (0x00007ffed294f000) libgh2mqtt.so (0x00007f4475a29000) libgh2mysql.so (0x0000

iOS基礎:獲取原始檔的方法

bundle是一個目錄,其中包含了程式會使用到的資源.這些資源包含了如影象,聲音,編譯好的程式碼,nib檔案(使用者也會把bundle稱為plug-in).對應bundle,cocoa提供了類NSB

C# 讀取原始檔.resx 中的xml資源

  主要是以字串的形式來讀取xml,然後通過遍歷讀取節點,通過節點屬性名稱獲取屬性值   /// <summary> /// 初始化OPC引數配置 /// </summary> /// <returns></returns> publi

excel巨集:列出一個目錄所有檔案並做也超連結

 從網上找了一些資訊,自己修改了一下 方式很直白,先把所有的目錄找了出來,然後一個個目錄來處理。 雖然與我習慣使用迭代的的方式有所差別,但也很好。 後面的函式是原始的,沒有改動,主函式自己重新寫過了。 檔案下載 '主函式 Sub ListFil

JAR打包webapp目錄資源

修改pom:<build><resources>            <resource>                <directory>${basedir}/src/main/webapp</directory&