feat(ui): fix debug mode exception on orientation change

This commit is contained in:
hyb1996
2018-09-08 01:53:51 +08:00
parent 32805aad34
commit c56157d8da
13 changed files with 127 additions and 40 deletions

View File

@@ -73,6 +73,7 @@
<activity
android:name=".ui.edit.EditActivity_"
android:configChanges="orientation|screenSize"
android:multiprocess="true"
android:theme="@style/EditorTheme">
</activity>
@@ -81,7 +82,10 @@
android:name=".ui.settings.SettingsActivity_"
android:theme="@style/AppTheme.Settings"/>
<activity android:name=".ui.error.ErrorReportActivity"/>
<activity android:name=".external.tasker.TaskerScriptEditActivity_"/>
<activity
android:name=".external.tasker.TaskerScriptEditActivity_"
android:configChanges="orientation|screenSize"
/>
<activity android:name=".ui.edit.ViewSampleActivity"/>
<activity
android:name=".ui.user.LoginActivity_"

View File

@@ -273,7 +273,10 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
private void initNormalToolbar() {
mNormalToolbar.setOnMenuItemClickListener(this);
showNormalToolbar();
Fragment fragment = getActivity().getSupportFragmentManager().findFragmentById(R.id.toolbar_menu);
if(fragment == null){
showNormalToolbar();
}
}
private void setUpFunctionsKeyboard() {
@@ -427,7 +430,7 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
private void showNormalToolbar() {
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.toolbar_menu, mNormalToolbar)
.commit();
.commitAllowingStateLoss();
}
FragmentActivity getActivity() {
@@ -618,6 +621,11 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
return mScriptExecutionId;
}
@Nullable
public ScriptExecution getScriptExecution(){
return AutoJs.getInstance().getScriptEngineService().getScriptExecution(mScriptExecutionId);
}
@Nullable
@Override
protected Parcelable onSaveInstanceState() {

View File

@@ -22,6 +22,8 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v7.widget.AppCompatEditText;
import android.text.Editable;
import android.text.Layout;
@@ -30,14 +32,17 @@ import android.util.Log;
import android.util.TimingLogger;
import android.view.Gravity;
import org.autojs.autojs.R;
import org.autojs.autojs.ui.edit.theme.Theme;
import org.autojs.autojs.ui.edit.theme.TokenMapping;
import com.stardust.autojs.execution.ScriptExecution;
import com.stardust.util.ClipboardUtil;
import com.stardust.util.TextUtils;
import org.mozilla.javascript.Token;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import static org.autojs.autojs.ui.edit.editor.BracketMatching.UNMATCHED_BRACKET;
@@ -137,12 +142,12 @@ public class CodeEditText extends AppCompatEditText {
private void drawLineHighlights(Canvas canvas) {
int currentLine = getCurrentLine();
int debugHighlightLine = mDebuggingLine;
if(debugHighlightLine != currentLine){
if (debugHighlightLine != currentLine) {
//绘制当前行高亮
mLineHighlightPaint.setColor(mTheme.getLineHighlightBackgroundColor());
drawLineHighlight(canvas, mLineHighlightPaint, getCurrentLine());
}
if(debugHighlightLine != -1){
if (debugHighlightLine != -1) {
mLineHighlightPaint.setColor(mTheme.getDebuggingLineBackgroundColor());
drawLineHighlight(canvas, mLineHighlightPaint, debugHighlightLine);
}
@@ -400,4 +405,34 @@ public class CodeEditText extends AppCompatEditText {
super.setSelection(index);
}
@Override
public Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
Parcelable superData = super.onSaveInstanceState();
bundle.putParcelable("super_data", superData);
bundle.putInt("debugging_line", mDebuggingLine);
int[] breakpoints = new int[mBreakpoints.size()];
int i = 0;
for (CodeEditor.Breakpoint breakpoint : mBreakpoints.values()) {
breakpoints[i++] = breakpoint.line;
}
bundle.putIntArray("breakpoints", breakpoints);
return bundle;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
Bundle bundle = (Bundle) state;
Parcelable superData = bundle.getParcelable("super_data");
mDebuggingLine = bundle.getInt("debugging_line", -1);
int[] breakpoints = bundle.getIntArray("breakpoints");
if(breakpoints != null){
for (int breakpoint : breakpoints) {
mBreakpoints.put(breakpoint, new CodeEditor.Breakpoint(breakpoint));
}
}
super.onRestoreInstanceState(superData);
}
}

View File

@@ -3,6 +3,7 @@ package org.autojs.autojs.ui.edit.editor;
import android.content.Context;
import android.graphics.Canvas;
import android.support.design.widget.Snackbar;
import android.text.Layout;
import android.util.AttributeSet;
import android.widget.Toast;
@@ -167,7 +168,8 @@ public class CodeEditor extends HVScrollView {
}
public void jumpTo(int line, int col) {
if (line >= mCodeEditText.getLayout().getLineCount() || line < 0) {
Layout layout = mCodeEditText.getLayout();
if (line < 0 || (layout != null && line >= layout.getLineCount())) {
return;
}
mCodeEditText.setSelection(mCodeEditText.getLayout().getLineStart(line) + col);
@@ -334,13 +336,14 @@ public class CodeEditor extends HVScrollView {
return mCodeEditText.getBreakpoints();
}
public void setDebuggingLine(int line){
public void setDebuggingLine(int line) {
jumpTo(line, 0);
mCodeEditText.setDebuggingLine(line);
}
public void addOrRemoveBreakpoint(int line) {
LinkedHashMap<Integer, Breakpoint> breakpoints = mCodeEditText.getBreakpoints();
if(breakpoints.remove(line) == null){
if (breakpoints.remove(line) == null) {
breakpoints.put(line, new Breakpoint(line));
}
mCodeEditText.invalidate();

View File

@@ -1,6 +1,5 @@
package org.autojs.autojs.ui.edit.toolbar;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -29,14 +28,11 @@ import java.util.List;
public class DebugToolbarFragment extends ToolbarFragment implements DebugCallback {
private static final String LOG_TAG = "DebugToolbarFragment";
private Dim mDim = new Dim();
private Dim mDim;
private EditorView mEditorView;
private Handler mHandler;
public DebugToolbarFragment() {
mDim.setGuiCallback(this);
mDim.setBreak();
mDim.attachTo(AutoJs.getInstance().getScriptEngineService(), ContextFactory.getGlobal());
Log.d(LOG_TAG, "DebugToolbarFragment()");
}
@@ -50,29 +46,54 @@ public class DebugToolbarFragment extends ToolbarFragment implements DebugCallba
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mEditorView = findEditorView(view);
mEditorView.run();
ScriptExecution scriptExecution = mEditorView.getScriptExecution();
if (scriptExecution != null) {
mDim = (Dim) scriptExecution.getEngine().getTag(Dim.TAG);
}
if (mDim == null) {
mDim = new Dim();
mDim.setBreak();
mDim.setBreakOnExceptions(true);
mDim.attachTo(AutoJs.getInstance().getScriptEngineService(), ContextFactory.getGlobal());
mDim.setGuiCallback(this);
setInterrupted(false);
mEditorView.run();
} else {
mDim.setGuiCallback(this);
}
Log.d(LOG_TAG, "onViewCreated");
}
private void setInterrupted(boolean interrupted) {
setMenuItemStatus(R.id.step_into, interrupted);
setMenuItemStatus(R.id.step_over, interrupted);
setMenuItemStatus(R.id.step_out, interrupted);
setMenuItemStatus(R.id.resume_script, interrupted);
if (!interrupted) {
mEditorView.getEditor().setDebuggingLine(-1);
}
}
public void detachDebugger() {
mDim.detach();
mDim.setGuiCallback(null);
}
@Click(R.id.step_over)
void stepOver() {
mEditorView.getEditor().setDebuggingLine(-1);
setInterrupted(false);
mDim.setReturnValue(Dim.STEP_OVER);
}
@Click(R.id.step_into)
void stepInto() {
mEditorView.getEditor().setDebuggingLine(-1);
setInterrupted(false);
mDim.setReturnValue(Dim.STEP_INTO);
}
@Click(R.id.stop_out)
@Click(R.id.step_out)
void stepOut() {
mEditorView.getEditor().setDebuggingLine(-1);
setInterrupted(false);
mDim.setReturnValue(Dim.STEP_OUT);
}
@@ -83,13 +104,13 @@ public class DebugToolbarFragment extends ToolbarFragment implements DebugCallba
@Click(R.id.resume_script)
void resumeScript() {
mEditorView.getEditor().setDebuggingLine(-1);
setInterrupted(false);
mDim.setReturnValue(Dim.GO);
}
@Override
public void updateSourceText(Dim.SourceInfo sourceInfo) {
Log.d(LOG_TAG, "updateSourceText: url = " + sourceInfo.url() + ", source = " + sourceInfo.source());
Log.d(LOG_TAG, "updateSourceText: url = " + sourceInfo.url());
if (!sourceInfo.url().equals(mEditorView.getFile().toString())) {
return;
}
@@ -107,7 +128,12 @@ public class DebugToolbarFragment extends ToolbarFragment implements DebugCallba
public void enterInterrupt(Dim.StackFrame stackFrame, String threadName, String s1) {
Log.d(LOG_TAG, "enterInterrupt: threadName = " + threadName + ", url = " + stackFrame.getUrl() + ", line = " + stackFrame.getLineNumber());
if (stackFrame.getUrl().equals(mEditorView.getFile().toString())) {
mEditorView.getEditor().setDebuggingLine(stackFrame.getLineNumber() - 1);
final int line = stackFrame.getLineNumber() - 1;
mHandler.post(() -> {
mEditorView.getEditor().setDebuggingLine(line);
setInterrupted(true);
});
} else {
mHandler.post(this::resumeScript);
}
@@ -120,25 +146,18 @@ public class DebugToolbarFragment extends ToolbarFragment implements DebugCallba
@Override
public void dispatchNextGuiEvent() {
Log.d(LOG_TAG, "dispatchNextGuiEvent");
}
@Override
public boolean shouldAttachDebugger(RhinoJavaScriptEngine engine) {
ScriptExecution execution = AutoJs.getInstance().getScriptEngineService().getScriptExecution(mEditorView.getScriptExecutionId());
ScriptExecution execution = mEditorView.getScriptExecution();
return execution != null && execution.getId() == engine.getId();
}
@Override
public List<Integer> getMenuItemIds() {
return Arrays.asList(R.id.step_over, R.id.step_into, R.id.stop_out, R.id.resume_script, R.id.stop_script);
return Arrays.asList(R.id.step_over, R.id.step_into, R.id.step_out, R.id.resume_script, R.id.stop_script);
}
@Override
public void onDestroy() {
super.onDestroy();
mDim.detach();
}
}

View File

@@ -5,6 +5,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollHorizontally="true"
android:imeOptions="flagNoExtractUi"
android:textColor="@android:color/transparent"
android:textCursorDrawable="@drawable/code_edit_text_cursor"
android:textSize="15sp"/>

View File

@@ -21,7 +21,7 @@
app:text="@string/text_debug_step_into"/>
<org.autojs.autojs.ui.widget.ToolbarMenuItem
android:id="@+id/stop_out"
android:id="@+id/step_out"
android:layout_width="40dp"
android:layout_height="match_parent"
app:icon="@drawable/ic_debug_step_out"

View File

@@ -1,6 +1,7 @@
package com.stardust.autojs;
import android.content.Context;
import android.os.Parcelable;
import android.support.annotation.Nullable;
import com.stardust.autojs.engine.JavaScriptEngine;
@@ -25,6 +26,9 @@ import com.stardust.util.UiHandler;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.mozilla.javascript.RhinoException;
import org.mozilla.javascript.ScriptStackElement;
import org.mozilla.javascript.WrappedException;
import java.io.BufferedReader;
import java.io.IOException;
@@ -209,7 +213,7 @@ public class ScriptEngineService {
@Nullable
public ScriptExecution getScriptExecution(int id) {
if(id == ScriptExecution.NO_ID){
if (id == ScriptExecution.NO_ID) {
return null;
}
return mScriptExecutions.get(id);
@@ -275,7 +279,17 @@ public class ScriptEngineService {
}
}
private static String getScriptTrace(Exception e) {
public static String getScriptTrace(Exception e) {
StringBuilder scriptTrace = new StringBuilder();
if (e instanceof RhinoException) {
RhinoException rhinoException = (RhinoException) e;
scriptTrace.append(rhinoException.details()).append("\n");
for (ScriptStackElement element : rhinoException.getScriptStack()) {
element.renderV8Style(scriptTrace);
scriptTrace.append("\n");
}
scriptTrace.append("- - - - - - - - - - -\n");
}
try {
PipedReader reader = new PipedReader(8192);
PrintWriter writer = new PrintWriter(new PipedWriter(reader));
@@ -283,10 +297,9 @@ public class ScriptEngineService {
writer.close();
BufferedReader bufferedReader = new BufferedReader(reader);
String line;
StringBuilder scriptTrace = new StringBuilder(TextUtils.toEmptyIfNull(e.getMessage()));
//scriptTrace.append(TextUtils.toEmptyIfNull(e.getMessage()));
while ((line = bufferedReader.readLine()) != null) {
if (line.trim().startsWith("at script"))
scriptTrace.append("\n").append(line);
scriptTrace.append("\n").append(line);
}
return scriptTrace.toString();
} catch (IOException e1) {

View File

@@ -4,6 +4,7 @@ import android.os.Handler;
import android.os.Looper;
import android.support.annotation.CallSuper;
import com.stardust.autojs.ScriptEngineService;
import com.stardust.autojs.engine.RhinoJavaScriptEngine;
import com.stardust.autojs.runtime.ScriptBridges;
import com.stardust.autojs.runtime.ScriptRuntime;
@@ -48,7 +49,7 @@ public class TimerThread extends ThreadCompat {
Looper.loop();
} catch (Exception e) {
if (!ScriptInterruptedException.causedByInterrupted(e)) {
mRuntime.console.error(Thread.currentThread().toString() + ": " + e);
mRuntime.console.error(Thread.currentThread().toString() + ": " + ScriptEngineService.getScriptTrace(e));
}
} finally {
onExit();

View File

@@ -32,6 +32,7 @@ public class Dim {
public static final int GO = 3;
public static final int BREAK = 4;
public static final int EXIT = 5;
public static final String TAG = Dim.class.getName();
// Constants for the DimIProxy interface implementation class.
private static final int IPROXY_DEBUG = 0;
@@ -1027,6 +1028,7 @@ public class Dim {
cx.setDebugger(debugger, contextData);
cx.setGeneratingDebug(true);
cx.setOptimizationLevel(-1);
engine.setTag(TAG, Dim.this);
}
@Override

View File

@@ -372,7 +372,7 @@ public class ScriptRuntime {
try {
events.emit("exit");
} catch (Exception ignored) {
console.error("exception on exit: " + ignored);
console.error("exception on exit: " + ScriptEngineService.getScriptTrace(ignored));
}
ignoresException(threads::shutDownAll);
ignoresException(events::recycle);

View File

@@ -1 +1 @@
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":401},"path":"commonRelease-4.0.0 Alpha1.apk","properties":{"packageId":"org.autojs.autojs","split":"","minSdkVersion":"17"}}]
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":408},"path":"commonRelease-4.0.2 Alpha3.apk","properties":{"packageId":"org.autojs.autojs","split":"","minSdkVersion":"17"}}]

View File

@@ -10,6 +10,7 @@ import com.stardust.auojs.inrt.BuildConfig;
import com.stardust.auojs.inrt.LogActivity;
import com.stardust.auojs.inrt.Pref;
import com.stardust.auojs.inrt.autojs.AutoJs;
import com.stardust.autojs.ScriptEngineService;
import com.stardust.autojs.execution.ExecutionConfig;
import com.stardust.autojs.execution.ScriptExecution;
import com.stardust.autojs.project.ProjectConfig;
@@ -73,7 +74,7 @@ public class AssetsProjectLauncher {
mScriptExecution = AutoJs.getInstance().getScriptEngineService().execute(source, new ExecutionConfig()
.executePath(mProjectDir));
} catch (Exception e) {
AutoJs.getInstance().getGlobalConsole().error(e);
AutoJs.getInstance().getGlobalConsole().error(ScriptEngineService.getScriptTrace(e));
}
}