import android.view.*;
import android.widget.*;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import java.io.*;
import java.lang.reflect.Method;
import java.net.*;
import dalvik.system.DexClassLoader;
public class main {
public static View main(final FragmentActivity context) {
ScrollView sv = new ScrollView(context);
LinearLayout ll = new LinearLayout(context);
ll.setOrientation(LinearLayout.VERTICAL);
LinearLayout line1 = new LinearLayout(context);
TextView label = new TextView(context);
label.setText("Run which snippet ID?");
line1.addView(label);
final EditText tv = new EditText(context);
tv.setText("675");
line1.addView(tv);
Button btnGo = new Button(context);
btnGo.setText("Go");
line1.addView(btnGo);
ll.addView(line1);
btnGo.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String snippetID = tv.getText().toString();
String text = "Running: " + snippetID;
Toast.makeText(context, text, 2000).show();
new DynamicRunner(context).run(snippetID);
}
});
sv.addView(ll);
return sv;
}
}
class DynamicRunner {
private static final String mainClassName = "main" /*"test"*/;
private static final String mainMethodName = "main" /*"run"*/;
private final FragmentActivity activity;
StringBuffer info = new StringBuffer();
public DynamicRunner(FragmentActivity activity) {
this.activity = activity;
}
public void run(String snippetID) {
try {
URL url = new URL(
/*"http://tinybrain.de/downloads/test.dex"*/
"http://tinybrain.de:8080/dexcompile.php?id=" + snippetID);
new DownloadFilesTask().execute(url);
} catch (Throwable e) {
showError(e);
}
}
static byte[] DEX_FILE_MAGIC = { 0x64, 0x65, 0x78, 0x0a, 0x30, 0x33, 0x35, 0x00 };
private Class<?> runDynamic(URL url) throws IOException, ClassNotFoundException {
info.append("Loading dex: " + url.toString() + "\n");
byte[] dexData = loadBinaryPage(url.openConnection());
if (!isDex(dexData))
throw new RuntimeException("Dex generation error: " + dexData.length + " bytes - " + new String(dexData, "UTF-8"));
info.append("Dex data length: " + dexData.length + "\n");
File dexDir = activity.getDir("dex", Context.MODE_PRIVATE);
File dexFile;
do {
dexFile = new File(dexDir, System.currentTimeMillis() + ".dex");
} while (dexFile.exists());
File dexOutputDir;
do {
dexOutputDir = activity.getDir("dex-optimized-" + System.currentTimeMillis(), Context.MODE_PRIVATE);
} while (dexOutputDir.list().length != 0);
FileOutputStream fileOutputStream = new FileOutputStream(dexFile);
fileOutputStream.write(dexData);
fileOutputStream.close();
ClassLoader parentClassLoader =
//ClassLoader.getSystemClassLoader(); // does not find support jar
//getClass().getClassLoader(); // Let's try this...
getClass().getClassLoader().getParent(); // XXX !
DexClassLoader classLoader = new DexClassLoader(dexFile.getAbsolutePath(), dexOutputDir.getAbsolutePath(), null,
parentClassLoader);
Class<?> theClass = classLoader.loadClass(mainClassName);
return theClass;
}
private boolean isDex(byte[] dexData) {
if (dexData.length < DEX_FILE_MAGIC.length) return false;
for (int i = 0; i < DEX_FILE_MAGIC.length; i++)
if (dexData[i] != DEX_FILE_MAGIC[i])
return false;
return true;
}
private void showError(Throwable e) {
ScrollView scrollView = new ScrollView(activity);
TextView errorView = new TextView(activity);
errorView.setText(info + "\n" + getStackTrace(e));
scrollView.addView(errorView);
activity.setContentView(scrollView);
}
public static String getStackTrace(Throwable throwable) {
StringWriter writer = new StringWriter();
throwable.printStackTrace(new PrintWriter(writer));
return writer.toString();
}
private class DownloadFilesTask extends AsyncTask<URL, Integer, Class<?>> {
volatile Throwable error;
URL url;
protected Class<?> doInBackground(URL... urls) {
try {
url = urls[0];
return runDynamic(url);
} catch (Throwable e) {
error = e;
return null;
}
}
protected void onProgressUpdate(Integer... progress) {
//setProgressPercent(progress[0]);
}
protected void onPostExecute(Class<?> theClass) {
try {
if (error != null)
showError(error);
else if (theClass != null) {
Method run = findMainMethod(theClass);
Object result = run.invoke(null, activity);
if (result instanceof Fragment) {
FragmentManager fm = activity.getSupportFragmentManager();
android.support.v4.app.Fragment fragment = fm.findFragmentByTag("mainFragment");
if (fragment == null) {
android.support.v4.app.FragmentTransaction ft = fm.beginTransaction();
fragment = (Fragment) result;
ft.add(android.R.id.content, fragment, "mainFragment");
ft.commit();
}
} else if (result instanceof View) {
activity.setContentView((View) result);
} else
showError(new Throwable("Bad return value from " + url + ", expected View or Fragment: " + result));
} else
showError(new Throwable("What?"));
} catch (Throwable e) {
showError(e);
}
}
}
static Method findMainMethod(Class<?> theClass) {
for (Method method : theClass.getMethods())
if (method.getName().equals(mainMethodName) && method.getParameterTypes().length == 1)
return method;
throw new RuntimeException("Method " + mainMethodName + " with 1 paramter not found in " + theClass.getName());
}
public static byte[] loadBinaryPage(URLConnection con) throws IOException {
//setHeaders(con);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
InputStream inputStream = con.getInputStream();
while (true) {
int ch = inputStream.read();
if (ch < 0)
break;
buf.write(ch);
}
inputStream.close();
return buf.toByteArray();
}
}
Began life as a copy of #676
download show line numbers debug dex old transpilations
Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
| Snippet ID: | #1000424 |
| Snippet name: | Boot code v1 for JavaX/Android (pre-transpilation, archived) |
| Eternal ID of this version: | #1000424/1 |
| Text MD5: | fdd2be32cae5ad7a0b5c60c6b6dd1bed |
| Author: | stefan |
| Category: | javax |
| Type: | JavaX source code |
| Public (visible to everyone): | Yes |
| Archived (hidden from active list): | No |
| Created/modified: | 2015-08-05 16:23:01 |
| Source code size: | 6636 bytes / 200 lines |
| Pitched / IR pitched: | No / Yes |
| Views / Downloads: | 1163 / 1073 |
| Referenced in: | #3000190 - Answer for stefanreich(>> t 20 questions) #3000382 - Answer for ferdie (>> t = 1, f = 0) #3000383 - Answer for funkoverflow (>> t=1, f=0 okay) |