Skip to content

Commit d38f4f4

Browse files
Merge pull request #773 from NativeScript/display-blocking-js
Manual instrumentation
2 parents 92ca4f3 + 3f67853 commit d38f4f4

File tree

16 files changed

+714
-328
lines changed

16 files changed

+714
-328
lines changed

build-artifacts/project-template-gradle/src/main/java/com/tns/NativeScriptApplication.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,15 @@ public NativeScriptApplication() {
1111
}
1212

1313
public void onCreate() {
14-
super.onCreate();
15-
com.tns.Runtime runtime = RuntimeHelper.initRuntime(this);
16-
if (runtime !=null) {
17-
runtime.run();
14+
ManualInstrumentation.Frame frame = ManualInstrumentation.start("NaitveScriptApplication.onCreate");
15+
try {
16+
super.onCreate();
17+
com.tns.Runtime runtime = RuntimeHelper.initRuntime(this);
18+
if (runtime != null) {
19+
runtime.run();
20+
}
21+
} finally {
22+
frame.close();
1823
}
1924
}
2025

build-artifacts/project-template-gradle/src/main/java/com/tns/RuntimeHelper.java

Lines changed: 135 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -53,157 +53,173 @@ public static Runtime initRuntime(Application app) {
5353
return Runtime.getCurrentRuntime();
5454
}
5555

56-
System.loadLibrary("NativeScript");
57-
58-
Logger logger = new LogcatLogger(app);
56+
ManualInstrumentation.Frame frame = ManualInstrumentation.start("RuntimeHelper.initRuntime");
57+
try {
58+
ManualInstrumentation.Frame loadLibraryFrame = ManualInstrumentation.start("loadLibrary NativeScript");
59+
try {
60+
System.loadLibrary("NativeScript");
61+
} finally {
62+
loadLibraryFrame.close();
63+
}
5964

60-
Runtime runtime = null;
61-
boolean showErrorIntent = hasErrorIntent(app);
62-
if (!showErrorIntent) {
63-
NativeScriptUncaughtExceptionHandler exHandler = new NativeScriptUncaughtExceptionHandler(logger, app);
65+
Logger logger = new LogcatLogger(app);
6466

65-
Thread.setDefaultUncaughtExceptionHandler(exHandler);
67+
Runtime runtime = null;
68+
boolean showErrorIntent = hasErrorIntent(app);
69+
if (!showErrorIntent) {
70+
NativeScriptUncaughtExceptionHandler exHandler = new NativeScriptUncaughtExceptionHandler(logger, app);
6671

67-
DefaultExtractPolicy extractPolicy = new DefaultExtractPolicy(logger);
68-
boolean skipAssetExtraction = Util.runPlugin(logger, app);
72+
Thread.setDefaultUncaughtExceptionHandler(exHandler);
6973

70-
String appName = app.getPackageName();
71-
File rootDir = new File(app.getApplicationInfo().dataDir);
72-
File appDir = app.getFilesDir();
74+
DefaultExtractPolicy extractPolicy = new DefaultExtractPolicy(logger);
75+
boolean skipAssetExtraction = Util.runPlugin(logger, app);
7376

74-
try {
75-
appDir = appDir.getCanonicalFile();
76-
} catch (IOException e1) {
77-
}
77+
String appName = app.getPackageName();
78+
File rootDir = new File(app.getApplicationInfo().dataDir);
79+
File appDir = app.getFilesDir();
7880

79-
if (!skipAssetExtraction) {
80-
if (logger.isEnabled()) {
81-
logger.write("Extracting assets...");
81+
try {
82+
appDir = appDir.getCanonicalFile();
83+
} catch (IOException e1) {
8284
}
8385

84-
AssetExtractor aE = new AssetExtractor(null, logger);
86+
if (!skipAssetExtraction) {
87+
ManualInstrumentation.Frame extractionFrame = ManualInstrumentation.start("Extracting assets");
88+
try {
89+
if (logger.isEnabled()) {
90+
logger.write("Extracting assets...");
91+
}
8592

86-
String outputDir = app.getFilesDir().getPath() + File.separator;
93+
AssetExtractor aE = new AssetExtractor(null, logger);
8794

88-
// will force deletion of previously extracted files in app/files directories
89-
// see https://github.com/NativeScript/NativeScript/issues/4137 for reference
90-
boolean removePreviouslyInstalledAssets = true;
91-
aE.extractAssets(app, "app", outputDir, extractPolicy, removePreviouslyInstalledAssets);
92-
aE.extractAssets(app, "internal", outputDir, extractPolicy, removePreviouslyInstalledAssets);
93-
aE.extractAssets(app, "metadata", outputDir, extractPolicy, false);
95+
String outputDir = app.getFilesDir().getPath() + File.separator;
9496

95-
boolean shouldExtractSnapshots = true;
97+
// will force deletion of previously extracted files in app/files directories
98+
// see https://github.com/NativeScript/NativeScript/issues/4137 for reference
99+
boolean removePreviouslyInstalledAssets = true;
100+
aE.extractAssets(app, "app", outputDir, extractPolicy, removePreviouslyInstalledAssets);
101+
aE.extractAssets(app, "internal", outputDir, extractPolicy, removePreviouslyInstalledAssets);
102+
aE.extractAssets(app, "metadata", outputDir, extractPolicy, false);
96103

97-
// will extract snapshot of the device appropriate architecture
98-
if (shouldExtractSnapshots) {
99-
if (logger.isEnabled()) {
100-
logger.write("Extracting snapshot blob");
101-
}
104+
boolean shouldExtractSnapshots = true;
102105

103-
aE.extractAssets(app, "snapshots/" + Build.CPU_ABI, outputDir, extractPolicy, removePreviouslyInstalledAssets);
104-
}
106+
// will extract snapshot of the device appropriate architecture
107+
if (shouldExtractSnapshots) {
108+
if (logger.isEnabled()) {
109+
logger.write("Extracting snapshot blob");
110+
}
105111

106-
extractPolicy.setAssetsThumb(app);
107-
}
112+
aE.extractAssets(app, "snapshots/" + Build.CPU_ABI, outputDir, extractPolicy, removePreviouslyInstalledAssets);
113+
}
108114

109-
AppConfig appConfig = new AppConfig(appDir);
110-
111-
ClassLoader classLoader = app.getClassLoader();
112-
File dexDir = new File(rootDir, "code_cache/secondary-dexes");
113-
String dexThumb = null;
114-
try {
115-
dexThumb = Util.getDexThumb(app);
116-
} catch (NameNotFoundException e) {
117-
if (logger.isEnabled()) {
118-
logger.write("Error while getting current proxy thumb");
115+
extractPolicy.setAssetsThumb(app);
116+
} finally {
117+
extractionFrame.close();
118+
}
119119
}
120-
e.printStackTrace();
121-
}
122-
123-
String nativeLibDir = null;
124-
try {
125-
nativeLibDir = app.getPackageManager().getApplicationInfo(appName, 0).nativeLibraryDir;
126-
} catch (android.content.pm.PackageManager.NameNotFoundException e) {
127-
e.printStackTrace();
128-
}
129120

130-
boolean isDebuggable = Util.isDebuggableApp(app);
131-
StaticConfiguration config = new StaticConfiguration(logger, appName, nativeLibDir, rootDir,
132-
appDir, classLoader, dexDir, dexThumb, appConfig, isDebuggable);
121+
AppConfig appConfig = new AppConfig(appDir);
122+
ManualInstrumentation.setMode(appConfig.getProfilingMode());
133123

134-
runtime = Runtime.initializeRuntimeWithConfiguration(config);
135-
if (isDebuggable) {
124+
ClassLoader classLoader = app.getClassLoader();
125+
File dexDir = new File(rootDir, "code_cache/secondary-dexes");
126+
String dexThumb = null;
136127
try {
137-
v8Inspector = new AndroidJsV8Inspector(app.getFilesDir().getAbsolutePath(), app.getPackageName());
138-
v8Inspector.start();
139-
140-
// the following snippet is used as means to notify the VSCode extension
141-
// debugger that the debugger agent has started
142-
File debuggerStartedFile = new File("/data/local/tmp", app.getPackageName() + "-debugger-started");
143-
if (debuggerStartedFile.exists() && !debuggerStartedFile.isDirectory() && debuggerStartedFile.length() == 0) {
144-
java.io.FileWriter fileWriter = new java.io.FileWriter(debuggerStartedFile);
145-
fileWriter.write("started");
146-
fileWriter.close();
147-
}
148-
149-
// check if --debug-brk flag has been set. If positive:
150-
// write to the file to invalidate the flag
151-
// inform the v8Inspector to pause the main thread
152-
File debugBreakFile = new File("/data/local/tmp", app.getPackageName() + "-debugbreak");
153-
boolean shouldBreak = false;
154-
if (debugBreakFile.exists() && !debugBreakFile.isDirectory() && debugBreakFile.length() == 0) {
155-
java.io.FileWriter fileWriter = new java.io.FileWriter(debugBreakFile);
156-
fileWriter.write("started");
157-
fileWriter.close();
158-
159-
shouldBreak = true;
128+
dexThumb = Util.getDexThumb(app);
129+
} catch (NameNotFoundException e) {
130+
if (logger.isEnabled()) {
131+
logger.write("Error while getting current proxy thumb");
160132
}
133+
e.printStackTrace();
134+
}
161135

162-
v8Inspector.waitForDebugger(shouldBreak);
163-
} catch (IOException e) {
136+
String nativeLibDir = null;
137+
try {
138+
nativeLibDir = app.getPackageManager().getApplicationInfo(appName, 0).nativeLibraryDir;
139+
} catch (android.content.pm.PackageManager.NameNotFoundException e) {
164140
e.printStackTrace();
165141
}
166-
}
167142

168-
// runtime needs to be initialized before the NativeScriptSyncService is enabled because it uses runtime.runScript(...)
169-
if (NativeScriptSyncService.isSyncEnabled(app)) {
170-
NativeScriptSyncService syncService = new NativeScriptSyncService(runtime, logger, app);
171-
172-
syncService.sync();
173-
syncService.startServer();
174-
175-
// preserve this instance as strong reference
176-
// do not preserve in NativeScriptApplication field inorder to
177-
// make the code more portable
178-
// @@@
179-
// Runtime.getOrCreateJavaObjectID(syncService);
180-
} else {
181-
if (logger.isEnabled()) {
182-
logger.write("NativeScript LiveSync is not enabled.");
143+
boolean isDebuggable = Util.isDebuggableApp(app);
144+
StaticConfiguration config = new StaticConfiguration(logger, appName, nativeLibDir, rootDir,
145+
appDir, classLoader, dexDir, dexThumb, appConfig, isDebuggable);
146+
147+
runtime = Runtime.initializeRuntimeWithConfiguration(config);
148+
if (isDebuggable) {
149+
try {
150+
v8Inspector = new AndroidJsV8Inspector(app.getFilesDir().getAbsolutePath(), app.getPackageName());
151+
v8Inspector.start();
152+
153+
// the following snippet is used as means to notify the VSCode extension
154+
// debugger that the debugger agent has started
155+
File debuggerStartedFile = new File("/data/local/tmp", app.getPackageName() + "-debugger-started");
156+
if (debuggerStartedFile.exists() && !debuggerStartedFile.isDirectory() && debuggerStartedFile.length() == 0) {
157+
java.io.FileWriter fileWriter = new java.io.FileWriter(debuggerStartedFile);
158+
fileWriter.write("started");
159+
fileWriter.close();
160+
}
161+
162+
// check if --debug-brk flag has been set. If positive:
163+
// write to the file to invalidate the flag
164+
// inform the v8Inspector to pause the main thread
165+
File debugBreakFile = new File("/data/local/tmp", app.getPackageName() + "-debugbreak");
166+
boolean shouldBreak = false;
167+
if (debugBreakFile.exists() && !debugBreakFile.isDirectory() && debugBreakFile.length() == 0) {
168+
java.io.FileWriter fileWriter = new java.io.FileWriter(debugBreakFile);
169+
fileWriter.write("started");
170+
fileWriter.close();
171+
172+
shouldBreak = true;
173+
}
174+
175+
v8Inspector.waitForDebugger(shouldBreak);
176+
} catch (IOException e) {
177+
e.printStackTrace();
178+
}
183179
}
184-
}
185180

186-
runtime.runScript(new File(appDir, "internal/ts_helpers.js"));
181+
// runtime needs to be initialized before the NativeScriptSyncService is enabled because it uses runtime.runScript(...)
182+
if (NativeScriptSyncService.isSyncEnabled(app)) {
183+
NativeScriptSyncService syncService = new NativeScriptSyncService(runtime, logger, app);
187184

188-
File javaClassesModule = new File(appDir, "app/tns-java-classes.js");
189-
if (javaClassesModule.exists()) {
190-
runtime.runModule(javaClassesModule);
191-
}
185+
syncService.sync();
186+
syncService.startServer();
192187

193-
try {
194-
// put this call in a try/catch block because with the latest changes in the modules it is not granted that NativeScriptApplication is extended through JavaScript.
195-
JavaScriptImplementation jsImpl = app.getClass().getAnnotation(JavaScriptImplementation.class);
196-
if (jsImpl != null) {
197-
Runtime.initInstance(app);
188+
// preserve this instance as strong reference
189+
// do not preserve in NativeScriptApplication field inorder to
190+
// make the code more portable
191+
// @@@
192+
// Runtime.getOrCreateJavaObjectID(syncService);
193+
} else {
194+
if (logger.isEnabled()) {
195+
logger.write("NativeScript LiveSync is not enabled.");
196+
}
198197
}
199-
} catch (Exception e) {
200-
if (logger.isEnabled()) {
201-
logger.write("Cannot initialize application instance.");
198+
199+
runtime.runScript(new File(appDir, "internal/ts_helpers.js"));
200+
201+
File javaClassesModule = new File(appDir, "app/tns-java-classes.js");
202+
if (javaClassesModule.exists()) {
203+
runtime.runModule(javaClassesModule);
204+
}
205+
206+
try {
207+
// put this call in a try/catch block because with the latest changes in the modules it is not granted that NativeScriptApplication is extended through JavaScript.
208+
JavaScriptImplementation jsImpl = app.getClass().getAnnotation(JavaScriptImplementation.class);
209+
if (jsImpl != null) {
210+
Runtime.initInstance(app);
211+
}
212+
} catch (Exception e) {
213+
if (logger.isEnabled()) {
214+
logger.write("Cannot initialize application instance.");
215+
}
216+
e.printStackTrace();
202217
}
203-
e.printStackTrace();
204218
}
219+
return runtime;
220+
} finally {
221+
frame.close();
205222
}
206-
return runtime;
207223
}
208224

209225
private static final String logTag = "MyApp";

0 commit comments

Comments
 (0)