Andoird開発デバッグ時にManifestを変更せずに任意のActivityを直接起動する方法
5773 ワード
Androidの開発デバッグでは、次の2つのケースがあります.複数人が開発する場合、各人がそれぞれ異なるActivityを処理する.この場合、異なるActivity間でスキップ機能が一時的に実現されないと、非MainActivity(デフォルトで起動したActivityを適用すると仮定)を処理する開発者は、現在処理しているActivityに直接起動およびスキップすることができなくなり、この場合、Manifestファイルを直接修正すると、異なる開発者のManifestファイルが異なる場合があり、コードの同期中にManifestが同期されると、毎回競合が発生します. 任意の場合、Activityの階層はより深く、すなわち、開始Activityから多層インタラクションを経て到達する.
どちらの場合も異なる解決策があるが,筆者はコードを変更せずに任意のActivityを初期起動できることを期待しているため,検討した.まず、adb shellによって異なるactionとcategoryのActivityをコマンドラインで起動することができ、通常、以下のコマンドによってMainActivity(デフォルト起動のActivityを適用すると仮定する)を起動することができる:adb shell am start-n com.vilyever/com.vilyever.ただし、MainActivityを別のActivityに置き換えると、エラー(java.lang.SecurityException:Permission Denial:starting Intent from null(pid=2413、uid=2000)が発生します.これは、通常、Activityは外部から勝手に起動することができないため、ManifestファイルにActivityにandroid:exported="true"属性を追加すると、Terminalでadb shell am start-n comが実行する.vilyever/com.vilyever.TestActivityは任意のActivityを起動できます
では、他の方法はありませんか?公式文書ADB Shell Commandsではadb shell am startの具体的なパラメータが提供されていないため,筆者は直接Terminalでadb shell am startを実行した結果,[-a][-d][-t][-c[-c]...][-e|--es ...] [--esn ...] [--ez ...] [--ei ...] [--el ...] [--ef ...] [--eu ...] [--ecn ] [--eia [, [--ela [, [--efa [, [-n ] [-f ] [--grant-read-uri-permission] [--grant-write-uri-permission] [--debug-log-resolution] [--exclude-stopped-packages] [--include-stopped-packages] [--activity-brought-to-front] [--activity-clear-top] [--activity-clear-when-task-reset] [--activity-exclude-from-recents] [--activity-launched-from-history] [--activity-multiple-task] [--activity-no-animation] [--activity-no-history] [--activity-no-user-action] [--activity-previous-is-top] [--activity-reorder-to-front] [--activity-reset-task-if-needed] [--activity-single-top] [--activity-clear-task] [--activity-task-on-home] [--receiver-registered-only] [--receiver-replace-pending] [--selector] [ | | ]
-aパラメータはActivityのactionを表し、-dパラメータはActivityのdataを表すことがわかります.筆者はブラウザ入力アドレスジャンプアプリをやったことがあるが,これを利用して特定のActivityを直接開くことができることを発見した.その後筆者はTestActivityのManifest宣言に追加するテストを行った.
このActivityはschemeでジャンプできることがわかります.そこでアプリケーションを実行した後、筆者はTerminalにadb shell am start-a androidと入力した.intent.action.VIEW -d vilyever://testactivity指定したActivityを開くことができます
どちらの方法でもTerminal入力コマンドで任意のActivityを開くことができますが、これには2つのステップが必要です. app を実行 adbコマンド を入力.
一歩で完成する可能性はありますか?筆者はgradleがappのインストールとadbコマンドの実行を実現できることをクエリーで発見し,それらを1つのtaskに集約することで任意のActivityを1つのキーで起動することができる.
appモジュールのbuild.gradleファイルの下にtaskを追加
どちらのtaskもActivityを起動することができ、最後のパラメータを変更すれば異なるActivityを起動してtaskを実行する方法を見ることができます:AS右のGradleを展開し、(Excute Gradle Task)円ボタンをクリックし、現在のプロジェクトを選択し、task名を入力し、OKをクリックして実行します
しかし
方法1:ManifestのActivityでandroid:exported="true"を追加する必要がある方法2:ManifestのActivityでschemeを追加する必要がある
これらのプロパティは、開発デバッグ時に一時的に追加されると、次の問題が発生する可能性があります. Activityの一部がこれらの属性を必要とする場合、アプリケーションの正式なリリース時に が誤って削除される可能性があります.アプリケーションの発行時にこれらの属性を削除することを忘れた場合、これらのActivityは外部から起動可能なインタフェースをすべて露出し、他の悪意のあるアプリケーションによって釣り詐欺などの行為として使用される可能性がある .
どのように解決しますか
任意のジャンプを実現するのはデバッグを容易にするためであるため、通常はdebugバージョンappを生成する際に使用され、debug時にManifestファイルを自動的に変更して任意のActivityの起動をサポートし、releaseバージョンをリリースする際に変更を行わないと、Activityごとに起動taskを追加するだけでこのニーズをスムーズに実現できます.gradleによってこの機能を実現することができ、appモジュールのbuild.gradleファイルの下のandroid{}が最後に追加されました
上記アプリケーションバリアント.all{}が実装する機能は、debug時にManifestでActivityがandroid:exported属性を宣言した場合、trueに変更することです.android:exportedが宣言されていない場合は、android:exported=「true」を追加します.
これにより、adb shell am start-n(パッケージ名)/(パッケージ名)を通過する.(Activity名)Activityとgradleを組み合わせたtaskを直接起動すれば、デバッグしたいActivityをワンクリックで起動できます.
以上が今回の研究の成果です.
どちらの場合も異なる解決策があるが,筆者はコードを変更せずに任意のActivityを初期起動できることを期待しているため,検討した.まず、adb shellによって異なるactionとcategoryのActivityをコマンドラインで起動することができ、通常、以下のコマンドによってMainActivity(デフォルト起動のActivityを適用すると仮定する)を起動することができる:adb shell am start-n com.vilyever/com.vilyever.ただし、MainActivityを別のActivityに置き換えると、エラー(java.lang.SecurityException:Permission Denial:starting Intent from null(pid=2413、uid=2000)が発生します.これは、通常、Activityは外部から勝手に起動することができないため、ManifestファイルにActivityにandroid:exported="true"属性を追加すると、Terminalでadb shell am start-n comが実行する.vilyever/com.vilyever.TestActivityは任意のActivityを起動できます
では、他の方法はありませんか?公式文書ADB Shell Commandsではadb shell am startの具体的なパラメータが提供されていないため,筆者は直接Terminalでadb shell am startを実行した結果,[-a][-d][-t][-c[-c]...][-e|--es ...] [--esn ...] [--ez ...] [--ei ...] [--el ...] [--ef ...] [--eu ...] [--ecn ] [--eia [, [--ela [, [--efa [, [-n ] [-f ] [--grant-read-uri-permission] [--grant-write-uri-permission] [--debug-log-resolution] [--exclude-stopped-packages] [--include-stopped-packages] [--activity-brought-to-front] [--activity-clear-top] [--activity-clear-when-task-reset] [--activity-exclude-from-recents] [--activity-launched-from-history] [--activity-multiple-task] [--activity-no-animation] [--activity-no-history] [--activity-no-user-action] [--activity-previous-is-top] [--activity-reorder-to-front] [--activity-reset-task-if-needed] [--activity-single-top] [--activity-clear-task] [--activity-task-on-home] [--receiver-registered-only] [--receiver-replace-pending] [--selector] [ | | ]
-aパラメータはActivityのactionを表し、-dパラメータはActivityのdataを表すことがわかります.筆者はブラウザ入力アドレスジャンプアプリをやったことがあるが,これを利用して特定のActivityを直接開くことができることを発見した.その後筆者はTestActivityのManifest宣言に追加するテストを行った.
このActivityはschemeでジャンプできることがわかります.そこでアプリケーションを実行した後、筆者はTerminalにadb shell am start-a androidと入力した.intent.action.VIEW -d vilyever://testactivity指定したActivityを開くことができます
どちらの方法でもTerminal入力コマンドで任意のActivityを開くことができますが、これには2つのステップが必要です.
一歩で完成する可能性はありますか?筆者はgradleがappのインストールとadbコマンドの実行を実現できることをクエリーで発見し,それらを1つのtaskに集約することで任意のActivityを1つのキーで起動することができる.
appモジュールのbuild.gradleファイルの下にtaskを追加
apply plugin: 'com.android.application' // application plugin
android {
...
}
dependencies {
...
}
// android:exported="true" Activity
task startExportedTestActivity(type: Exec, dependsOn: 'installDebug') {
commandLine 'cmd', '/c', 'adb', 'shell', 'am', 'start', '-n', 'com.vilyever/com.vilyever.TestActivity'
}
// scheme Activity
task startSchemeTestActivity(type: Exec, dependsOn: 'installDebug') {
commandLine 'cmd', '/c', 'adb', 'shell', 'am', 'start', '-a', 'android.intent.action.VIEW', '-d', 'vilyever://testactivity'
}
どちらのtaskもActivityを起動することができ、最後のパラメータを変更すれば異なるActivityを起動してtaskを実行する方法を見ることができます:AS右のGradleを展開し、(Excute Gradle Task)円ボタンをクリックし、現在のプロジェクトを選択し、task名を入力し、OKをクリックして実行します
しかし
方法1:ManifestのActivityでandroid:exported="true"を追加する必要がある方法2:ManifestのActivityでschemeを追加する必要がある
これらのプロパティは、開発デバッグ時に一時的に追加されると、次の問題が発生する可能性があります.
どのように解決しますか
任意のジャンプを実現するのはデバッグを容易にするためであるため、通常はdebugバージョンappを生成する際に使用され、debug時にManifestファイルを自動的に変更して任意のActivityの起動をサポートし、releaseバージョンをリリースする際に変更を行わないと、Activityごとに起動taskを追加するだけでこのニーズをスムーズに実現できます.gradleによってこの機能を実現することができ、appモジュールのbuild.gradleファイルの下のandroid{}が最後に追加されました
apply plugin: 'com.android.application' // application plugin
android {
...
applicationVariants.all { variant ->
variant.outputs.each { output ->
if ("${variant.dirName}".contains("debug")) {
output.processManifest.doLast {
def manifestOutFile = output.processManifest.manifestOutputFile
def activities = manifestOutFile.getText('UTF-8').split("")) {
newFileContents = newFileContents + "
上記アプリケーションバリアント.all{}が実装する機能は、debug時にManifestでActivityがandroid:exported属性を宣言した場合、trueに変更することです.android:exportedが宣言されていない場合は、android:exported=「true」を追加します.
これにより、adb shell am start-n(パッケージ名)/(パッケージ名)を通過する.(Activity名)Activityとgradleを組み合わせたtaskを直接起動すれば、デバッグしたいActivityをワンクリックで起動できます.
以上が今回の研究の成果です.