Libraryless. Click here for Pure Java version (895L/7K/23K).
1 | !752 |
2 | |
3 | import java.util.*; |
4 | import java.util.zip.*; |
5 | import java.util.List; |
6 | import java.util.regex.*; |
7 | import java.util.concurrent.*; |
8 | import java.util.concurrent.atomic.*; |
9 | import java.io.*; |
10 | import java.net.*; |
11 | import java.lang.reflect.*; |
12 | import java.lang.ref.*; |
13 | import java.lang.management.*; |
14 | import java.security.*; |
15 | import java.security.spec.*; |
16 | import java.math.*; |
17 | |
18 | import android.widget.*; |
19 | import android.view.*; |
20 | import android.view.View; |
21 | import android.widget.Button; |
22 | import android.content.Context; |
23 | import android.app.Activity; |
24 | import android.view.inputmethod.*; |
25 | import android.content.*; |
26 | import android.text.*; |
27 | |
28 | public class main { |
29 | static String awarenessID = "#1004078"; |
30 | |
31 | static Class x30; |
32 | |
33 | static List<Prog> programsStarted = new ArrayList<Prog>(); |
34 | static File defSnip, defargs; |
35 | |
36 | static class Prog { |
37 | String snippetID; |
38 | Thread thread; |
39 | } |
40 | |
41 | static class Lg { |
42 | static int maxBufferLength = 2048; |
43 | |
44 | Activity context; |
45 | ScrollView sv; |
46 | TextView tv; |
47 | StringBuilder buf = new StringBuilder(); |
48 | |
49 | Lg(Activity context) { |
50 | this.context = context; |
51 | sv = new ScrollView(context); |
52 | tv = new TextView(context); |
53 | tv.setText(buf.toString()); |
54 | sv.addView(tv); |
55 | } |
56 | |
57 | View getView() { |
58 | return sv; |
59 | } |
60 | |
61 | void shortenBuffer() { |
62 | while (buf.length() > maxBufferLength) { |
63 | String s = buf.toString(); |
64 | int i = s.indexOf('\n'); |
65 | if (i < 0) return; |
66 | buf = new StringBuilder(s.substring(i+1)); |
67 | } |
68 | } |
69 | |
70 | void print(final String s) { |
71 | context.runOnUiThread(new Runnable() { |
72 | public void run() { |
73 | buf.append(s); |
74 | shortenBuffer(); |
75 | tv.setText(buf.toString()); |
76 | |
77 | sv.post(new Runnable() { |
78 | public void run() { |
79 | // This method works but animates the scrolling |
80 | // which looks weird on first load |
81 | sv.fullScroll(View.FOCUS_DOWN); |
82 | |
83 | // This method works even better because there are no animations. |
84 | //sv.scrollTo(0, sv.getBottom()); |
85 | } |
86 | }); |
87 | } |
88 | }); |
89 | } |
90 | |
91 | void println(String s) { |
92 | print(s + "\n"); |
93 | } |
94 | } |
95 | |
96 | public static String snippetToRun; |
97 | static Context androidContext; |
98 | |
99 | public static View main(final Context _context) throws Exception { |
100 | final Activity context = _context instanceof Activity ? (Activity) _context : null; |
101 | |
102 | System.out.println("676 context: " + _context); |
103 | |
104 | androidContext = _context; |
105 | |
106 | if (context == null) { |
107 | if (snippetToRun != null) { |
108 | new Thread() { |
109 | public void run() { |
110 | String[] a = { snippetToRun }; |
111 | callx30(a); |
112 | } |
113 | }.start(); |
114 | } |
115 | return null; |
116 | } |
117 | |
118 | defSnip = new File(userHome(), ".javax/defsnip"); |
119 | String id = loadTextFile(defSnip.getPath(), "636"); |
120 | defargs = new File(userHome(), ".javax/defargs"); |
121 | String arg = loadTextFile(defargs.getPath(), ""); |
122 | |
123 | ScrollView sv = new ScrollView(context); |
124 | LinearLayout ll = new LinearLayout(context); |
125 | ll.setOrientation(LinearLayout.VERTICAL); |
126 | |
127 | LinearLayout line1 = new LinearLayout(context); |
128 | |
129 | TextView label = new TextView(context); |
130 | label.setText("Run which snippet ID?"); |
131 | line1.addView(label); |
132 | |
133 | final EditText tv = new EditText(context); |
134 | // BAD - tv.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL); |
135 | tv.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_CLASS_NUMBER); |
136 | tv.setText(id); |
137 | line1.addView(tv); |
138 | |
139 | Button btnGo = new Button(context); |
140 | btnGo.setText("Go"); |
141 | line1.addView(btnGo); |
142 | |
143 | ll.addView(line1); |
144 | |
145 | LinearLayout line2 = new LinearLayout(context); |
146 | |
147 | label = new TextView(context); |
148 | label.setText("Program arguments:"); |
149 | line2.addView(label); |
150 | |
151 | final EditText tvArgs = new EditText(context); |
152 | tvArgs.setText(arg); |
153 | line2.addView(tvArgs); |
154 | |
155 | ll.addView(line2); |
156 | |
157 | LinearLayout line3 = new LinearLayout(context); |
158 | |
159 | /*Button btnLeo = new Button(context); |
160 | btnLeo.setText("Sprechen mit Leo"); |
161 | line3.addView(btnLeo);*/ |
162 | |
163 | Button btn = new Button(context); |
164 | btn.setText("Start Awareness [" + awarenessID + "]"); |
165 | btn.setOnClickListener(new View.OnClickListener() { |
166 | public void onClick(View v) { |
167 | saveDef(awarenessID, ""); |
168 | run(context, awarenessID, new String[0]); |
169 | } |
170 | }); |
171 | line3.addView(btn); |
172 | |
173 | ll.addView(line3); |
174 | |
175 | btnGo.setOnClickListener(new View.OnClickListener() { |
176 | public void onClick(View v) { |
177 | hideKeyboard(context); |
178 | String snippetID = tv.getText().toString(); |
179 | String text = "Running: " + snippetID; |
180 | Toast.makeText(context, text, 2000).show(); |
181 | |
182 | saveDef(snippetID, tvArgs.getText().toString()); |
183 | |
184 | // TODO: quoted args |
185 | run(context, snippetID, tvArgs.getText().toString().split(" +")); |
186 | } |
187 | }); |
188 | |
189 | sv.addView(ll); |
190 | return sv; |
191 | } |
192 | |
193 | static void saveDef(String snippetID, String args) { |
194 | try { |
195 | saveTextFile(defSnip.getPath(), snippetID); |
196 | saveTextFile(defargs.getPath(), args); |
197 | } catch (IOException e) { |
198 | } |
199 | } |
200 | |
201 | static Lg lg; |
202 | |
203 | public static void run(final Activity context, final String mainSnippet, final String[] args) { |
204 | lg = new Lg(context); |
205 | |
206 | OutputStream outputStream = new OutputStream() { |
207 | public void write(int b) { |
208 | try { |
209 | lg.print(new String(new byte[] {(byte) b}, "UTF-8")); // This is crap |
210 | } catch (UnsupportedEncodingException e) {} |
211 | } |
212 | |
213 | @Override |
214 | public void write(byte[] b, int off, int len) { |
215 | try { |
216 | lg.print(new String(b, off, len, "UTF-8")); // This is crap |
217 | } catch (UnsupportedEncodingException e) {} |
218 | } |
219 | }; |
220 | |
221 | PrintStream ps = new PrintStream(outputStream, true); |
222 | System.setOut(ps); |
223 | System.setErr(ps); |
224 | |
225 | Prog prog = new Prog(); |
226 | prog.snippetID = mainSnippet; |
227 | |
228 | prog.thread = new Thread() { |
229 | public void run() { |
230 | try { |
231 | String[] a = new String[args.length+1]; |
232 | System.arraycopy(args, 0, a, 1, args.length); |
233 | a[0] = mainSnippet; |
234 | callx30(a); |
235 | } catch (Throwable e) { |
236 | System.out.println("Whoa!"); |
237 | e.printStackTrace(); |
238 | } |
239 | } |
240 | }; |
241 | |
242 | programsStarted.add(prog); |
243 | prog.thread.start(); |
244 | |
245 | context.setContentView(lg.getView()); |
246 | } |
247 | |
248 | static void setContentViewInUIThread(final View view) { |
249 | ((Activity) androidContext).runOnUiThread(new Runnable() { |
250 | public void run() { |
251 | ((Activity) androidContext).setContentView(view); |
252 | } |
253 | }); |
254 | } |
255 | |
256 | public static void hideKeyboard(Activity context) { |
257 | View view = context.getCurrentFocus(); |
258 | if (view != null) { |
259 | InputMethodManager inputManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); |
260 | inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); |
261 | } |
262 | } |
263 | |
264 | static void onActivityResult(int requestCode, int resultCode, Intent data) { |
265 | /* TODO? |
266 | if (x30.mainClass != null) |
267 | x30.call(x30.mainClass, "onActivityResult", requestCode, resultCode, data);*/ |
268 | } |
269 | |
270 | static void callx30(S[] args) { |
271 | getx30(); |
272 | callMain(x30, args); |
273 | } |
274 | |
275 | static synchronized void getx30() { |
276 | if (x30 == null) |
277 | x30 = loadDex("#1004182"); |
278 | } |
279 | |
280 | static Class<?> loadDex(String programID) ctex { |
281 | S url = "http://tinybrain.de:8080/dexcompile.php?id=" + parseSnippetID(programID); |
282 | byte[] dexData = loadBinaryPage(url); |
283 | if (!isDex(dexData)) |
284 | throw new RuntimeException("Dex generation error"); |
285 | System.out.println("Dex loaded: " + dexData.length + "b"); |
286 | |
287 | File dexDir = makeAndroidTempDir(); |
288 | File dexFile = new File(dexDir, System.currentTimeMillis() + ".dex"); |
289 | File dexOutputDir = makeAndroidTempDir(); |
290 | |
291 | System.out.println("Saving dex to: " + dexDir.getAbsolutePath()); |
292 | try { |
293 | saveBinaryFile(dexFile.getPath(), dexData); |
294 | } catch (Throwable e) { |
295 | System.out.println("Whoa!"); |
296 | throw new RuntimeException(e); |
297 | } |
298 | |
299 | System.out.println("Getting parent class loader."); |
300 | ClassLoader parentClassLoader = |
301 | main.class.getClassLoader().getParent(); |
302 | |
303 | //System.out.println("Making DexClassLoader."); |
304 | //DexClassLoader classLoader = new DexClassLoader(dexFile.getAbsolutePath(), dexOutputDir.getAbsolutePath(), null, |
305 | // parentClassLoader); |
306 | Class dcl = Class.forName("dalvik.system.DexClassLoader"); |
307 | Object classLoader = dcl.getConstructors()[0].newInstance(dexFile.getAbsolutePath(), dexOutputDir.getAbsolutePath(), null, |
308 | parentClassLoader); |
309 | |
310 | //System.out.println("Loading main class."); |
311 | //Class<?> theClass = classLoader.loadClass(mainClassName); |
312 | Class<?> theClass = (Class<?>) call(classLoader, "loadClass", "main"); |
313 | |
314 | //System.out.println("Main class loaded."); |
315 | try { |
316 | set(theClass, "androidContext", androidContext); |
317 | } catch (Throwable e) {} |
318 | |
319 | setVars(theClass, programID); |
320 | return theClass; |
321 | } |
322 | |
323 | static void setVars(Class<?> theClass, String programID) { |
324 | try { |
325 | set(theClass, "programID", programID); |
326 | } catch (Throwable e) {} |
327 | |
328 | try { |
329 | set(theClass, "__javax", x30); |
330 | } catch (Throwable e) {} |
331 | } |
332 | } |
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: | #1004180 |
Snippet name: | Boot-up code for JavaX/Android, loading x30 dynamically (dev.) |
Eternal ID of this version: | #1004180/1 |
Text MD5: | 8f28190571215c818b4133fada21794f |
Transpilation MD5: | 77ba85a1f144f22c5b45ffa622c4490c |
Author: | stefan |
Category: | javax |
Type: | JavaX source code (Android) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2016-08-09 15:26:37 |
Source code size: | 9694 bytes / 332 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 582 / 618 |
Referenced in: | [show references] |