Running a 20k lines JS file make app no response
LiuHongtao opened this issue · 5 comments
I ran a 20k lines JS file like below. It made the app no response, or sometimes the first run is well.
var string;
var x;
var mycars = new Array();
mycars = new Array();
mycars[0] = "Saab";
mycars[1] = "Volvo";
mycars[2] = "BMW";
mycars = new Array();
mycars[0] = "Saab";
mycars[1] = "Volvo";
mycars[2] = "BMW";
mycars = new Array();
mycars[0] = "Saab";
mycars[1] = "Volvo";
mycars[2] = "BMW";
...
Activity code:
JSContext context;
long time = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = new JSContext();
}
public void toRunJS(View view) {
String js = getFromAssets("test.js");
context.evaluateScript(js);
context.garbageCollect();
}
and Layout code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.lht.jscoredemo.MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="RunJs"
android:onClick="toRunJS"/>
</RelativeLayout>
Actually I want to run a 30k lines JS library and it's more complex than this, so I beg for your help.
Hi. Don't run JS in the UI thread. It will cause problems. Run it
asynchronously. Try this:
public void toRunJS(View view) {
final String js = getFromAssets("test.js");
new Thread() {
@Override public run() {
context.evaluateScript(js);
context.garbageCollect(); // <-- not really necessary
}
}).start();
}
On Tue, Sep 13, 2016 at 9:53 AM, 刘宏韬 notifications@github.com wrote:
I ran a 20k lines JS file like below. It made the app no response, or
sometimes the first run is well.var string;
var x;
var mycars = new Array();
mycars = new Array();
mycars[0] = "Saab";
mycars[1] = "Volvo";
mycars[2] = "BMW";mycars = new Array();
mycars[0] = "Saab";
mycars[1] = "Volvo";
mycars[2] = "BMW";mycars = new Array();
mycars[0] = "Saab";
mycars[1] = "Volvo";
mycars[2] = "BMW";...
Activity code:
JSContext context;
long time = 0;@OverRide
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);context = new JSContext();
}
public void toRunJS(View view) {
String js = getFromAssets("test.js");
context.evaluateScript(js);
context.garbageCollect();
}and Layout code:
<Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="RunJs" android:onClick="toRunJS"/>
Actually I want to run a 30k lines JS library and it's more complex than
this, so I beg for your help.—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#40, or mute the
thread
https://github.com/notifications/unsubscribe-auth/ABIuZCmnXdnrQe13XyfOETLRM3JxZ3rBks5qpiVCgaJpZM4J7R2w
.
I rewrite the code and move JS code to a new thread. But problem still exists.
There is the new code:
public class MainActivity extends AppCompatActivity {
static JSContext jsContext;
String js;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
jsContext = new JSContext();
jsContext.property("log", new JSFunction(jsContext, "log") {
public void log(String msg) {
Log.d("MainActivityLog", msg);
}
});
jsContext.property("screenWidth", 768);
jsContext.property("screenHeight", 1038);
js = getFromAssets("test.js");
thread.start();
}
Thread thread = new Thread() {
@Override
public void run() {
super.run();
jsContext.evaluateScript(js);
}
};
public void toRunJS(View view) {
Intent intent = new Intent();
intent.setClass(this, Main2Activity.class);
startActivity(intent);
}
}
public class Main2Activity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
JSObject object = new JSObject(MainActivity.jsContext);
}
}
The test.js is a 15k lines JS. When button clicked, code dead here:
JSObject object = new JSObject(MainActivity.jsContext);
public JSObject(JSContext ctx) {
→ context = ctx;
...
}
But if i remove one of three properties, it goes well:
jsContext.property("log", new JSFunction(jsContext, "log") {
public void log(String msg) {
Log.d("MainActivityLog", msg);
}
});
jsContext.property("screenHeight", 1038);
It always hangs in the same place? That is a surprising place for it to die. It is difficult for me to debug without a failing test case that I can reproduce. Can you provide the js? You can run it through uglify or whatever. I don't actually need to see it. The JS code is not the problem. I just need something which reproduces the issue reliably.
I'll send you an email with the test project.
Hi, I just commented on the issue "Multithreading and deadlock" and I wondered if this ticket was actually the same problem - Is it possible that the thing hanging this project is not the size of the evaluated JS, but instead the amount of data being passed into the "log" JSFunction via the JS <--> Java interface?
As a data-point, we can correctly evaluate a 350Kb JS file with no issues.