Skip to content

Commit 7342221

Browse files
feat: read main activity from AndroidManifest.xml automatically (#1967)
* feat: read main activity from `AndroidManifest.xml` automatically * test: update e2e snaphosts * test: add test scenario for main activity as class name * chore: types cleanup * chore: code cleaning * fix: tests
1 parent bd496c4 commit 7342221

File tree

18 files changed

+276
-18
lines changed

18 files changed

+276
-18
lines changed

__e2e__/__snapshots__/config.test.ts.snap

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ exports[`shows up current config without unnecessary output 1`] = `
6565
"android": {
6666
"sourceDir": "<<REPLACED_ROOT>>/TestProject/android",
6767
"appName": "app",
68-
"packageName": "com.testproject"
68+
"packageName": "com.testproject",
69+
"mainActivity": ".MainActivity"
6970
}
7071
}
7172
}

docs/platforms.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ type AndroidProjectConfig = {
8484
sourceDir: string;
8585
appName: string;
8686
packageName: string;
87+
mainActivity: string;
8788
dependencyConfiguration?: string;
8889
watchModeCommandParams: string;
8990
};

packages/cli-config/src/__tests__/index-test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,12 +406,28 @@ test('should convert project sourceDir relative path to absolute', () => {
406406
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
407407
xmlns:tools="http://schemas.android.com/tools"
408408
package="com.coinbase.android">
409+
<application android:name=".MainApplication">
410+
<activity android:name=".MainActivity">
411+
<intent-filter>
412+
<action android:name="android.intent.action.MAIN" />
413+
<category android:name="android.intent.category.LAUNCHER" />
414+
</intent-filter>
415+
</activity>
416+
</application>
409417
</manifest>
410418
`,
411419
'android2/AndroidManifest.xml': `
412420
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
413421
xmlns:tools="http://schemas.android.com/tools"
414422
package="com.coinbase.android">
423+
<application android:name=".MainApplication">
424+
<activity android:name=".MainActivity">
425+
<intent-filter>
426+
<action android:name="android.intent.action.MAIN" />
427+
<category android:name="android.intent.category.LAUNCHER" />
428+
</intent-filter>
429+
</activity>
430+
</application>
415431
</manifest>
416432
`,
417433
});

packages/cli-platform-android/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"@react-native-community/cli-tools": "12.0.0-alpha.10",
1111
"chalk": "^4.1.2",
1212
"execa": "^5.0.0",
13+
"fast-xml-parser": "^4.2.4",
1314
"glob": "^7.1.3",
1415
"logkitty": "^0.7.1"
1516
},

packages/cli-platform-android/src/commands/runAndroid/__tests__/runOnAllDevices.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ describe('--appFolder', () => {
6767
appName: 'app',
6868
packageName: 'com.test',
6969
sourceDir: '/android',
70+
mainActivity: '.MainActivity',
7071
};
7172
beforeEach(() => {
7273
jest.clearAllMocks();

packages/cli-platform-android/src/commands/runAndroid/index.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,11 @@ async function runAndroid(_argv: Array<string>, config: Config, args: Flags) {
105105
}
106106
}
107107

108-
const androidProject = getAndroidProject(config);
108+
let androidProject = getAndroidProject(config);
109+
110+
if (args.mainActivity) {
111+
androidProject.mainActivity = args.mainActivity;
112+
}
109113

110114
return buildAndRun(args, androidProject);
111115
}
@@ -294,12 +298,8 @@ function installAndLaunchOnDevice(
294298
androidProject,
295299
selectedTask,
296300
);
297-
tryLaunchAppOnDevice(
298-
selectedDevice,
299-
androidProject.packageName,
300-
adbPath,
301-
args,
302-
);
301+
302+
tryLaunchAppOnDevice(selectedDevice, androidProject, adbPath, args);
303303
}
304304

305305
export default {
@@ -338,7 +338,6 @@ export default {
338338
{
339339
name: '--main-activity <string>',
340340
description: 'Name of the activity to start',
341-
default: 'MainActivity',
342341
},
343342
{
344343
name: '--deviceId <string>',

packages/cli-platform-android/src/commands/runAndroid/runOnAllDevices.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ async function runOnAllDevices(
110110
if (args.binaryPath && device) {
111111
tryInstallAppOnDevice(args, adbPath, device, androidProject);
112112
}
113-
tryLaunchAppOnDevice(device, androidProject.packageName, adbPath, args);
113+
tryLaunchAppOnDevice(device, androidProject, adbPath, args);
114114
},
115115
);
116116
}

packages/cli-platform-android/src/commands/runAndroid/tryLaunchAppOnDevice.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,25 @@
77
*/
88

99
import execa from 'execa';
10-
import {Flags} from '.';
10+
import {AndroidProject, Flags} from '.';
1111
import {logger, CLIError} from '@react-native-community/cli-tools';
1212

1313
function tryLaunchAppOnDevice(
1414
device: string | void,
15-
packageName: string,
15+
androidProject: AndroidProject,
1616
adbPath: string,
1717
args: Flags,
1818
) {
1919
const {appId, appIdSuffix} = args;
20+
const {packageName, mainActivity} = androidProject;
21+
2022
const packageNameWithSuffix = [appId || packageName, appIdSuffix]
2123
.filter(Boolean)
2224
.join('.');
2325

24-
const activityToLaunch = args.mainActivity.includes('.')
25-
? args.mainActivity
26-
: [packageName, args.mainActivity].filter(Boolean).join('.');
26+
const activityToLaunch = mainActivity.includes('.')
27+
? mainActivity
28+
: [packageName, mainActivity].filter(Boolean).join('.');
2729

2830
try {
2931
// Here we're using the same flags as Android Studio to launch the app

packages/cli-platform-android/src/config/__fixtures__/android.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ const appBuildGradle = fs.readFileSync(
2222
path.join(__dirname, './files/appbuild.gradle'),
2323
);
2424

25+
const fewActivitiesManifest = fs.readFileSync(
26+
path.join(__dirname, './files/AndroidManifest-few-activities.xml'),
27+
);
28+
29+
const classNameManifest = fs.readFileSync(
30+
path.join(__dirname, './files/AndroidManifest-className.xml'),
31+
);
32+
2533
function generateValidFileStructureForLib(classFileName: string) {
2634
return {
2735
'build.gradle': buildGradle,
@@ -278,3 +286,15 @@ export const findPackagesClassNameJavaNotValid = [
278286
}
279287
`,
280288
];
289+
290+
export const fewActivities = {
291+
src: {
292+
'AndroidManifest.xml': fewActivitiesManifest,
293+
},
294+
};
295+
296+
export const className = {
297+
src: {
298+
'AndroidManifest.xml': classNameManifest,
299+
},
300+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.some.example">
2+
<uses-permission android:name="android.permission.INTERNET" />
3+
4+
<application android:name=".MainApplication">
5+
<activity android:name="com.example.ExampleAppActivity">
6+
<intent-filter>
7+
<action android:name="android.intent.action.MAIN" />
8+
<category android:name="android.intent.category.LAUNCHER" />
9+
</intent-filter>
10+
</activity>
11+
</application>
12+
</manifest>

0 commit comments

Comments
 (0)