Intereting Posts
Сессия Предоставляется для запроса в неоткрытом состоянии Не удалось выполнить идентификатор метода dex: не в : 65536 Стиль панели инструментов Android Spinner Espresso: return boolean, если вид существует Экспорт android в csv и отправка в виде вложения электронной почты Воспроизведение видео, когда активность скрыта Адресная строка браузера веб-браузера (хром) изменяет значение $ (window) .height (); Создание фонового размера: масштабирование обложки каждый раз «Недостаточно информации для вывода параметра T» с помощью Kotlin и Android Задача Gradle изменить логическое значение в конфигурации сборки Могу ли я создать интерфейс в Xamarin.Forms с помощью XAML Ускорьте время разработки проекта Android в IntelliJ IDEA Проблемы с размером стека Android? Панель инструментов setNavigationOnClickListener разрывает функциональность ActionbarDrawerToggle Исключение: пакет Android не относится к 2000 Android, как использовать checktextview

Когда использовать какой конструктор для ComponentName в Android?

Я немного запутался в классе ComponentName в Android.

Существуют разные способы доступа к объекту с именем компонента, но я не знаю, когда использовать его … и почему!

Пример:

  • Пакет приложений – de.zordid.sampleapp
  • Но класс поставщика виджетов – de.zordid.sampleapp.widget.WidgetProvider

С помощью

 ComponentName cn = new ComponentName("de.zordid.sampleapp.widget", "WidgetProvider"); 

Я получил эту информацию о компоненте: ComponentInfo{de.zordid.sampleapp.widget/WidgetProvider} , но я не мог использовать это – компонент неизвестен! Но JavaDoc говорит, что я должен предоставить пакет и класс внутри этого пакета – и это то, что я сделал, не так ли?

С помощью

 ComponentName cn = new ComponentName(context, WidgetProvider.class); 

ComponentInfo{de.zordid.sampleapp/de.zordid.sampleapp.widget.WidgetProvider} – и это отлично работает !!

Существует еще один способ получить ComponentName – по контексту и строке. Какой из них следует использовать где и когда?

Благодаря!

Solutions Collecting From Web of "Когда использовать какой конструктор для ComponentName в Android?"

Конструктор ComponentName с двумя String s может использоваться для ссылки на компонент в другом приложении. Но первым аргументом является не имя пакета класса; Это имя пакета приложения — атрибут package элемента manifest в AndroidManifest.xml этого приложения. Итак, ваш первый пример должен быть

 ComponentName cn = new ComponentName("de.zordid.sampleapp", "de.zordid.sampleapp.widget.WidgetProvider"); 

Этот конструктор, безусловно, можно использовать для ссылки на компоненты в вашем собственном приложении, но поскольку у вас уже есть Context из вашего собственного приложения, вы можете его использовать и использовать один из других конструкторов. По моему мнению, тот, кто принимает Class должен быть предпочтительным, когда он используется. Вы можете использовать тот, который берет String если вы только знаете класс динамически по какой-либо причине; В этом случае он должен взять полностью квалифицированное имя класса, как указано выше.

Или вы можете использовать это внутри BroadcastReceiver:

 ComponentName smsReceiver = new ComponentName(this, SMSReceiver.class); 

Ответ Роберта Тупело-Шнека прав насчет предпочтения объектов против Строков. Вот как я это вижу.

  • Чтобы обратиться к своим собственным компонентам, используйте:

     new ComponentName(getApplicationContext(), WidgetProvider.class); 
  • Чтобы ссылаться на какой-то компонент с динамическим ссылкой в ​​вашем собственном приложении, используйте:

     // values/strings.xml: <string name="provider">de.zordid.sampleapp.widget.WidgetProvider</string> String fqcn = getResources().getString(R.string.provider); new ComponentName(getApplicationContext(), fqcn); 

    Это полезно, когда вы хотите использовать квалификаторы ресурсов Android для определения того, какой компонент использовать, вы можете переопределить строку по умолчанию в values-*/strings.xml .

  • Чтобы обратиться к компоненту другого приложения, используйте:

     int componentFlags = GET_ACTIVITIES | GET_PROVIDERS | GET_RECEIVERS | GET_SERVICES; PackageInfo otherApp = context.getPackageManager().getPackageInfo("com.other.app", componentFlags); ComponentInfo info = otherApp.activities[i]; // or providers/receivers/... new ComponentName(info.packageName, info.name); 

О именах и <manifest package="

Здесь может быть некоторая путаница, потому что я считаю, что исторически утверждение Роберта было правдой:

Это имя пакета приложения — атрибут пакета элемента манифеста в AndroidManifest.xml этого приложения

Но не больше. С момента появления новой системы сборки Gradle здесь произошли некоторые изменения .

Если у вас есть android.defaultConfig.applicationId указанный в вашем build.gradle , это будет имя пакета приложения, а затем атрибут package в манифесте – отдельная вещь при создании вашего приложения. Первый аргумент ComponentName теперь относится к applicationId + applicationIdSuffix . Трудность в том, что после окончательного слияния и упаковки манифеста APK будет иметь <manifest package=applicationId + applicationIdSuffix и все .Names будут расширены до FQCN.

Пример приложения для определения разрешения имен

Вот пример структуры, основанной на структуре одного из моих приложений. Рассмотрите следующие классы в гипотетическом приложении под названием «приложение»:

  • net.twisterrob.app.android.App
  • net.twisterrob.app.android.GlideSetup
  • net.twisterrob.app.android.subpackage.SearchResultsActivity
  • net.twisterrob.app.android.subpackage.Activity
  • net.twisterrob.app.android.content.AppProvider

На стороне сервера на стороне приложения и / или некоторых общих классах моделей:

  • net.twisterrob.app.data.*
  • net.twisterrob.app.backend.*
  • net.twisterrob.app.web.*

В моей вспомогательной библиотеке Android:

  • net.twisterrob.android.activity.AboutActivity

Другие библиотеки:

  • android.support.v4.content.FileProvider

Таким образом, все net.twisterrob.app в net.twisterrob.app . Приложение для Android – это всего лишь одна часть целого внутри собственного подпакета.

AndroidManifest.xml (несоответствующие части опущены)

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="net.twisterrob.app.android"> <!-- `package` above defines the base package for .Names to simplify reading/writing the manifest. Notice that it's different than the `applicationId` in build.gradle and can be independently changed in case you want to refactor your packages. This way you can still publish the same app with the same name. --> <!-- Will be expanded to net.twisterrob.app.android.App in the manifest merging phase. --> <application android:name=".App"> <!-- meta-data needs FQCNs because the merger can't know if you want to expand them or not. Also notice that name and value both can contain class names, depending on what you use. --> <meta-data android:name="net.twisterrob.app.android.GlideSetup" android:value="GlideModule" /> <meta-data android:name="android.app.default_searchable" android:value="net.twisterrob.app.android.subpackage.SearchResultsActivity" /> <!-- Will be expanded to net.twisterrob.app.android.subpackage.Activity in the manifest merging phase. --> <activity android:name=".subpackage.Activity" /> <!-- Needs full qualification because it's not under the package defined on manifest element. --> <activity android:name="net.twisterrob.android.activity.AboutActivity" /> <!-- Will be expanded to net.twisterrob.app.android.content.AppProvider in the manifest merging phase. --> <provider android:name=".content.AppProvider" android:authorities="${applicationId}" /> <!-- Needs full qualification because it's not under the package defined on manifest element. --> <provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.share" /> </application> <!-- ${applicationId} will be replaced with what's defined in `build.gradle` --> </manifest> 

build.gradle

 android { defaultConfig { // this is what will be used when you upload it to the Play Store applicationId 'net.twisterrob.app' } buildTypes { debug { // The neatest trick ever! // Released application: net.twisterrob.app // IDE built debug application: net.twisterrob.app.debug // This will allow you to have your installed released version // and sideloaded debug application at the same time working independently. // All the ContentProvider authorities within a system must have a unique name // so using ${applicationId} as authority will result in having two different content providers. applicationIdSuffix '.debug' } } } 

Чтобы узнать, как будет выглядеть ваш последний манифест, после слияния open build\intermediates\manifests\full\debug\AndroidManifest.xml .