Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

200
LINES

< > BotCompany Repo | #1000424 // Boot code v1 for JavaX/Android (pre-transpilation, archived)

JavaX source code - run with: x30.jar

1  
import android.view.*;
2  
import android.widget.*;
3  
import android.content.Context;
4  
5  
import android.os.AsyncTask;
6  
import android.support.v4.app.Fragment;
7  
import android.support.v4.app.FragmentActivity;
8  
import android.support.v4.app.FragmentManager;
9  
10  
import java.io.*;
11  
import java.lang.reflect.Method;
12  
import java.net.*;
13  
14  
import dalvik.system.DexClassLoader;
15  
16  
public class main {
17  
  public static View main(final FragmentActivity context) {
18  
    ScrollView sv = new ScrollView(context);
19  
    LinearLayout ll = new LinearLayout(context);
20  
    ll.setOrientation(LinearLayout.VERTICAL);
21  
    
22  
    LinearLayout line1 = new LinearLayout(context);
23  
    
24  
    TextView label = new TextView(context);
25  
    label.setText("Run which snippet ID?");
26  
    line1.addView(label);
27  
    
28  
    final EditText tv = new EditText(context);
29  
    tv.setText("675");
30  
    line1.addView(tv);
31  
    
32  
    Button btnGo = new Button(context);
33  
    btnGo.setText("Go");
34  
    line1.addView(btnGo);
35  
    
36  
    ll.addView(line1);
37  
    
38  
    btnGo.setOnClickListener(new View.OnClickListener() {
39  
      public void onClick(View v) {
40  
        String snippetID = tv.getText().toString();
41  
        String text = "Running: " + snippetID;
42  
        Toast.makeText(context, text, 2000).show();
43  
        new DynamicRunner(context).run(snippetID);
44  
      }
45  
    });
46  
47  
    sv.addView(ll);
48  
    return sv;
49  
  }
50  
}
51  
52  
class DynamicRunner {
53  
  private static final String mainClassName = "main" /*"test"*/;
54  
  private static final String mainMethodName = "main" /*"run"*/;
55  
56  
  private final FragmentActivity activity;
57  
58  
  StringBuffer info = new StringBuffer();
59  
60  
  public DynamicRunner(FragmentActivity activity) {
61  
    this.activity = activity;
62  
  }
63  
64  
  public void run(String snippetID) {
65  
    try {
66  
      URL url = new URL(
67  
                    /*"http://tinybrain.de/downloads/test.dex"*/
68  
        "http://tinybrain.de:8080/dexcompile.php?id=" + snippetID);
69  
      new DownloadFilesTask().execute(url);
70  
    } catch (Throwable e) {
71  
      showError(e);
72  
    }
73  
  }
74  
  static byte[] DEX_FILE_MAGIC = { 0x64, 0x65, 0x78, 0x0a, 0x30, 0x33, 0x35, 0x00 };
75  
76  
  private Class<?> runDynamic(URL url) throws IOException, ClassNotFoundException {
77  
    info.append("Loading dex: " + url.toString() + "\n");
78  
    byte[] dexData = loadBinaryPage(url.openConnection());
79  
    if (!isDex(dexData))
80  
      throw new RuntimeException("Dex generation error: " + dexData.length + " bytes - " + new String(dexData, "UTF-8"));
81  
    info.append("Dex data length: " + dexData.length + "\n");
82  
    
83  
    File dexDir = activity.getDir("dex", Context.MODE_PRIVATE);
84  
    File dexFile;
85  
    do {
86  
      dexFile = new File(dexDir, System.currentTimeMillis() + ".dex");
87  
    } while (dexFile.exists());
88  
    
89  
    File dexOutputDir;
90  
    do {
91  
      dexOutputDir = activity.getDir("dex-optimized-" + System.currentTimeMillis(), Context.MODE_PRIVATE);
92  
    } while (dexOutputDir.list().length != 0);
93  
94  
    FileOutputStream fileOutputStream = new FileOutputStream(dexFile);
95  
    fileOutputStream.write(dexData);
96  
    fileOutputStream.close();
97  
98  
    ClassLoader parentClassLoader =
99  
      //ClassLoader.getSystemClassLoader(); // does not find support jar
100  
      //getClass().getClassLoader(); // Let's try this...
101  
      getClass().getClassLoader().getParent(); // XXX !
102  
    DexClassLoader classLoader = new DexClassLoader(dexFile.getAbsolutePath(), dexOutputDir.getAbsolutePath(), null,
103  
      parentClassLoader);
104  
    Class<?> theClass = classLoader.loadClass(mainClassName);
105  
    return theClass;
106  
  }
107  
108  
  private boolean isDex(byte[] dexData) {
109  
    if (dexData.length < DEX_FILE_MAGIC.length) return false;
110  
    for (int i = 0; i < DEX_FILE_MAGIC.length; i++)
111  
      if (dexData[i] != DEX_FILE_MAGIC[i])
112  
        return false;
113  
    return true;
114  
  }
115  
116  
  private void showError(Throwable e) {
117  
    ScrollView scrollView = new ScrollView(activity);
118  
119  
    TextView errorView = new TextView(activity);
120  
    errorView.setText(info + "\n" + getStackTrace(e));
121  
    scrollView.addView(errorView);
122  
123  
    activity.setContentView(scrollView);
124  
  }
125  
126  
  public static String getStackTrace(Throwable throwable) {
127  
    StringWriter writer = new StringWriter();
128  
    throwable.printStackTrace(new PrintWriter(writer));
129  
    return writer.toString();
130  
  }
131  
132  
  private class DownloadFilesTask extends AsyncTask<URL, Integer, Class<?>> {
133  
    volatile Throwable error;
134  
    URL url;
135  
136  
    protected Class<?> doInBackground(URL... urls) {
137  
      try {
138  
        url = urls[0];
139  
        return runDynamic(url);
140  
      } catch (Throwable e) {
141  
        error = e;
142  
        return null;
143  
      }
144  
    }
145  
146  
    protected void onProgressUpdate(Integer... progress) {
147  
      //setProgressPercent(progress[0]);
148  
    }
149  
150  
    protected void onPostExecute(Class<?> theClass) {
151  
      try {
152  
        if (error != null)
153  
          showError(error);
154  
        else if (theClass != null) {
155  
          Method run = findMainMethod(theClass);
156  
          Object result = run.invoke(null, activity);
157  
158  
          if (result instanceof Fragment) {
159  
            FragmentManager fm = activity.getSupportFragmentManager();
160  
            android.support.v4.app.Fragment fragment = fm.findFragmentByTag("mainFragment");
161  
            if (fragment == null) {
162  
              android.support.v4.app.FragmentTransaction ft = fm.beginTransaction();
163  
              fragment = (Fragment) result;
164  
              ft.add(android.R.id.content, fragment, "mainFragment");
165  
              ft.commit();
166  
            }
167  
          } else if (result instanceof View) {
168  
            activity.setContentView((View) result);
169  
          } else
170  
            showError(new Throwable("Bad return value from " + url + ", expected View or Fragment: " + result));
171  
        } else
172  
          showError(new Throwable("What?"));
173  
      } catch (Throwable e) {
174  
        showError(e);
175  
      }
176  
    }
177  
  }
178  
179  
  static Method findMainMethod(Class<?> theClass) {
180  
    for (Method method : theClass.getMethods())
181  
      if (method.getName().equals(mainMethodName) && method.getParameterTypes().length == 1)
182  
        return method;
183  
    throw new RuntimeException("Method " + mainMethodName + " with 1 paramter not found in " + theClass.getName());
184  
  }
185  
186  
  public static byte[] loadBinaryPage(URLConnection con) throws IOException {
187  
    //setHeaders(con);
188  
    ByteArrayOutputStream buf = new ByteArrayOutputStream();
189  
    InputStream inputStream = con.getInputStream();
190  
    while (true) {
191  
      int ch = inputStream.read();
192  
      if (ch < 0)
193  
        break;
194  
      buf.write(ch);
195  
    }
196  
    inputStream.close();
197  
    return buf.toByteArray();
198  
  }
199  
200  
}

Author comment

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: 546 / 492
Referenced in: [show references]