Android applicationId與package的區別 install failed conflicting provider bug

應用ID與包名區別

每個Android應用都有一個唯一的應用ID.在Android設備和市場上,這個ID是你應用的唯一標識.若想在市場上更新應用,新應用的ID必須和原來apk的應用ID一致.所以一旦發佈了應用,就不能再改變應用ID.


在Eclipse中沒有applicationId這個概念,Eclipse中applicationId即等同於包名。但是到了Android Studio中,這兩個概念做個區分。包名的定義在清單文件中:

[html] view plain copy
  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     package="com.example.myapplicationtest" >  
應用ID是在moudle層的build.gradle中定義,applicationId值即爲應用ID,如下所示:

[java] view plain copy
  1. android {  
  2.     defaultConfig {  
  3.         applicationId "com.example.myapplicationtest"  
  4.         minSdkVersion 15  
  5.         targetSdkVersion 24  
  6.         versionCode 1  
  7.         versionName "1.0"  
  8.     }  
  9.     ...  
  10. }  

但是,在Android Studio中創建一個新項目時,applicationId默認是和項目的包名一致的。所以常常有開發者會將兩者混淆,以爲它們是一個概念。實際上,應用ID和包名是相互獨立的。改變包名不會影響應用ID,反之亦然。

通常Android的應用ID與包名是綁定的,所以在Android API中,一些方法和參數從名稱上看似乎它們返回的是包名,事實上它們返回的是應用ID值.例如,Context.getPackageName()方法返回的是應用ID,而不是包名。不信我們來看:


圖中,包名是:com.example.myapplicationtest   應用ID:com.example.myapplicationtest.id

在MainActivity中調用如下代碼:

[java] view plain copy
  1. String applicationId = this.getPackageName();  
  2. Log.i("TESTKIM","applicationId:" + applicationId);  
打印日誌文件,如下:



應用ID的命名並不是隨意的,它至少需要需遵循以下限制:

  • 應用ID至少包含兩部分(也就是說至少有一個點,如com.example);

  • 每部分必須以字母開頭;

  • 所有字符必須是字母數字或者下劃線[a-zA-Z0-9_]

注意:

如果你使用了webview,請使用包名作爲應用ID的前綴,否則,有可能會報錯.


應用ID用處

應用ID除了唯一標識了應用,那麼它在開發過程中可以有哪些用處呢?

試想一下,當我們開發應用的時候,要在一臺測試機上同時裝上開發版和發佈版,如何才能做到呢?其實很簡單,只要讓開發版的應用ID與發佈版不一致即可。所以,只需要在buildTypes中修改開發版的應用ID就行。如下:

[java] view plain copy
  1. android {  
  2.     ...  
  3.     buildTypes {  
  4.         debug {  
  5.             applicationIdSuffix ".debug"   //等同於“com.example.myapplicationtest.debug”  
  6.         }  
  7.     }  
  8. }  

上面代碼中,將debug版的應用ID在原來應用ID後追加“.debug”。applicationIdSuffix代表了默認的應用ID,即爲defaultConfig中applicationId的值。所以,debug版的應用ID爲:"com.example.myapplicationtest.debug".


另外,有時我們發佈到市場的應用希望有不同的版本,比如:免費版和收費版。這就需要我們來構建不同的應用變體。那麼我們可以在productFlavors中進行相應的配置,來生成不同的應用。如:

android {
    defaultConfig {
        applicationId "com.example.myapplicationtest"
    }
    productFlavors {
        free {
            applicationIdSuffix ".free"
        }
        paid {
            applicationIdSuffix ".paid"
        }
    }
}
在上面的代碼中,我們用"free"表示免費版,用"paid"表示付費版。在productFlavors中,通過配置不同應用ID,最終生成不同的應用。最終這兩種應用apk可同時存在於市場中。


修改包名

默認情況下,包名與應用ID是相同的。當然,開發者也可以對包名進行修改.如果開發者想要修改包名的話,注意項目目錄結構必須與AndroidManifest.xml中package屬性的包名一致.

[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="com.example.myapplicationtest"  
  4.     android:versionCode="1"  
  5.     android:versionName="1.0" >  

package值有兩個作用:

  • 它爲R.java文件提供了命名空間,例如R class的包名爲com.example.myappcationtest.R

  • 決定manifest中聲明的class的相對名稱。如:manifest中聲明的<activity android:name=".MainActivity"> 的真實路徑爲:com.example.myapplicationtest.ManiActivity

如果開發者想修改包名,必須確保manifest中package值也做了同步修改.



如果出現 INSTALL FAILED CONFLICTING PROVIDER錯誤,請檢查下面紅色部分是否相同

<provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:grantUriPermissions="true" android:exported="false"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章