ruboto 0.15.0 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +4 -1
- data/README.md +44 -43
- data/RELEASE_CANDICATE_DOC +10 -12
- data/RELEASE_DOC +69 -37
- data/Rakefile +47 -27
- data/assets/rakelib/ruboto.rake +69 -26
- data/assets/src/RubotoActivity.java +17 -4
- data/assets/src/RubotoService.java +18 -0
- data/assets/src/org/ruboto/EntryPointActivity.java +1 -1
- data/assets/src/org/ruboto/JRubyAdapter.java +3 -1
- data/assets/src/org/ruboto/ScriptLoader.java +27 -4
- data/assets/src/ruboto/activity.rb +4 -3
- data/assets/src/ruboto/activity/reload.rb +17 -12
- data/assets/src/ruboto/widget.rb +18 -18
- data/bin/elevate.exe +0 -0
- data/bin/elevate_32.exe +0 -0
- data/lib/java_class_gen/android_api.xml +1 -1
- data/lib/ruboto/commands/base.rb +3 -5
- data/lib/ruboto/util/build.rb +1 -1
- data/lib/ruboto/util/emulator.rb +31 -5
- data/lib/ruboto/util/setup.rb +183 -68
- data/lib/ruboto/util/update.rb +35 -42
- data/lib/ruboto/util/xml_element.rb +45 -33
- data/lib/ruboto/version.rb +1 -1
- data/test/activity/call_super_activity.rb +1 -1
- data/test/activity/dialog_fragment_activity.rb +37 -0
- data/test/activity/dialog_fragment_activity_test.rb +19 -0
- data/test/activity/image_button_activity.rb +2 -1
- data/test/activity/navigation_activity_test.rb +2 -1
- data/test/activity/no_on_create_activity.rb +17 -0
- data/test/activity/no_on_create_activity_test.rb +15 -0
- data/test/activity/spinner_activity.rb +51 -0
- data/test/activity/spinner_activity_test.rb +65 -0
- data/test/activity/stack_activity_test.rb +14 -7
- data/test/activity/startup_exception_activity.rb +7 -5
- data/test/activity/startup_exception_activity_test.rb +2 -2
- data/test/app_test_methods.rb +4 -0
- data/test/git_based_gem_test.rb +64 -0
- data/test/minimal_app_test.rb +12 -13
- data/test/rake_test.rb +1 -0
- data/test/ruboto_gen_test.rb +21 -15
- data/test/ruboto_update_test.rb +23 -6
- data/test/sqldroid_test.rb +0 -1
- data/test/test_helper.rb +37 -19
- metadata +25 -2
data/assets/rakelib/ruboto.rake
CHANGED
@@ -34,7 +34,7 @@ adb_version_str = `adb version`
|
|
34
34
|
(puts "Unrecognized adb version: #$1"; exit 1) unless adb_version_str =~ /Android Debug Bridge version (\d+\.\d+\.\d+)/
|
35
35
|
(puts "adb version 1.0.31 or later required. Version found: #$1"; exit 1) unless Gem::Version.new($1) >= Gem::Version.new('1.0.31')
|
36
36
|
android_home = ENV['ANDROID_HOME']
|
37
|
-
android_home = android_home.gsub("\\",
|
37
|
+
android_home = android_home.gsub("\\", '/') unless android_home.nil?
|
38
38
|
if android_home.nil?
|
39
39
|
if (adb_path = which('adb'))
|
40
40
|
android_home = File.dirname(File.dirname(adb_path))
|
@@ -235,27 +235,25 @@ end
|
|
235
235
|
|
236
236
|
file RUBOTO_CONFIG_FILE
|
237
237
|
|
238
|
+
task :jruby_adapter => JRUBY_ADAPTER_FILE
|
238
239
|
file JRUBY_ADAPTER_FILE => RUBOTO_CONFIG_FILE do
|
239
240
|
require 'yaml'
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
241
|
+
marker_topic ='Ruboto HeapAlloc'
|
242
|
+
begin_marker = "// BEGIN #{marker_topic}"
|
243
|
+
end_marker = "// END #{marker_topic}"
|
244
|
+
unless (heap_alloc = YAML.load(File.read(RUBOTO_CONFIG_FILE))['heap_alloc'])
|
245
|
+
heap_alloc = 13
|
246
|
+
comment = '// '
|
247
|
+
end
|
248
|
+
config = <<EOF
|
249
|
+
#{begin_marker}
|
250
|
+
#{comment}@SuppressWarnings("unused")
|
251
|
+
#{comment}byte[] arrayForHeapAllocation = new byte[#{heap_alloc} * 1024 * 1024];
|
252
|
+
#{comment}arrayForHeapAllocation = null;
|
253
|
+
#{end_marker}
|
247
254
|
EOF
|
248
|
-
else
|
249
|
-
config = <<EOF
|
250
|
-
// BEGIN Ruboto HeapAlloc
|
251
|
-
// @SuppressWarnings("unused")
|
252
|
-
// byte[] arrayForHeapAllocation = new byte[13 * 1024 * 1024];
|
253
|
-
// arrayForHeapAllocation = null;
|
254
|
-
// END Ruboto HeapAlloc
|
255
|
-
EOF
|
256
|
-
end
|
257
255
|
source = File.read(JRUBY_ADAPTER_FILE)
|
258
|
-
heap_alloc_pattern = %r{^\s
|
256
|
+
heap_alloc_pattern = %r{^\s*#{begin_marker}\n.*^\s*#{end_marker}\n}m
|
259
257
|
File.open(JRUBY_ADAPTER_FILE, 'w') { |f| f << source.sub(heap_alloc_pattern, config) }
|
260
258
|
end
|
261
259
|
|
@@ -281,6 +279,9 @@ task :update_scripts => %w(install:quick) do
|
|
281
279
|
update_scripts
|
282
280
|
end
|
283
281
|
|
282
|
+
desc 'Copy scripts to emulator or device and reload'
|
283
|
+
task :boing => %w(update_scripts:reload)
|
284
|
+
|
284
285
|
namespace :update_scripts do
|
285
286
|
desc 'Copy scripts to emulator and restart the app'
|
286
287
|
task :restart => APK_DEPENDENCIES - RUBY_SOURCE_FILES do |t|
|
@@ -299,7 +300,7 @@ namespace :update_scripts do
|
|
299
300
|
else
|
300
301
|
update_scripts
|
301
302
|
end
|
302
|
-
start_app
|
303
|
+
start_app
|
303
304
|
end
|
304
305
|
|
305
306
|
desc 'Copy scripts to emulator and reload'
|
@@ -309,7 +310,13 @@ namespace :update_scripts do
|
|
309
310
|
start_app
|
310
311
|
else
|
311
312
|
scripts = update_scripts
|
312
|
-
|
313
|
+
if scripts
|
314
|
+
if app_running?
|
315
|
+
reload_scripts(scripts)
|
316
|
+
else
|
317
|
+
start_app
|
318
|
+
end
|
319
|
+
end
|
313
320
|
end
|
314
321
|
end
|
315
322
|
end
|
@@ -380,6 +387,10 @@ file BUNDLE_JAR => [GEM_FILE, GEM_LOCK_FILE] do
|
|
380
387
|
definition = Bundler.definition
|
381
388
|
definition.validate_ruby!
|
382
389
|
Bundler::Installer.install(Bundler.root, definition)
|
390
|
+
unless Dir["#{BUNDLE_PATH}/bundler/gems/"].empty?
|
391
|
+
system("mkdir -p '#{BUNDLE_PATH}/gems'")
|
392
|
+
system("mv #{BUNDLE_PATH}/bundler/gems/* #{BUNDLE_PATH}/gems/")
|
393
|
+
end
|
383
394
|
|
384
395
|
# Restore RUBY_ENGINE (limit the scope of this hack)
|
385
396
|
old_verbose, $VERBOSE = $VERBOSE, nil
|
@@ -389,7 +400,7 @@ file BUNDLE_JAR => [GEM_FILE, GEM_LOCK_FILE] do
|
|
389
400
|
$VERBOSE = old_verbose
|
390
401
|
end
|
391
402
|
Gem.platforms = platforms
|
392
|
-
Gem.paths = gem_paths[
|
403
|
+
Gem.paths = gem_paths['GEM_PATH']
|
393
404
|
else
|
394
405
|
# Bundler.settings[:platform] = Gem::Platform::DALVIK
|
395
406
|
sh "bundle install --gemfile #{GEM_FILE} --path=#{BUNDLE_PATH} --platform=dalvik#{sdk_level}"
|
@@ -527,6 +538,35 @@ Java::json.ext.ParserService.new.basicLoad(JRuby.runtime)
|
|
527
538
|
FileUtils.rm_rf BUNDLE_PATH
|
528
539
|
end
|
529
540
|
|
541
|
+
desc 'Log activity execution, accepts optional logcat filter'
|
542
|
+
task :log, [:filter] do |t, args|
|
543
|
+
puts '--- clearing logcat'
|
544
|
+
`adb logcat -c`
|
545
|
+
filter = args[:filter] ? args[:filter] : '' # filter log with filter-specs like TAG:LEVEL TAG:LEVEL ... '*:S'
|
546
|
+
logcat_cmd = "adb logcat ActivityManager #{filter}" # we always need ActivityManager logging to catch activity start
|
547
|
+
puts "--- starting logcat: #{logcat_cmd}"
|
548
|
+
IO.popen logcat_cmd do |logcat|
|
549
|
+
puts "--- waiting for activity #{package}/.#{main_activity} ..."
|
550
|
+
activity_started = false
|
551
|
+
started_regex = Regexp.new "^\\I/ActivityManager.+Start proc #{package} for activity #{package}/\\.#{main_activity}: pid=(?<pid>\\d+)"
|
552
|
+
restarted_regex = Regexp.new "^\\I/ActivityManager.+START u0 {cmp=#{package}/org.ruboto.RubotoActivity.+} from pid (?<pid>\\d+)"
|
553
|
+
related_regex = Regexp.new "#{package}|#{main_activity}"
|
554
|
+
pid_regex = nil
|
555
|
+
logcat.each_line do |line|
|
556
|
+
if (activity_start_match = started_regex.match(line) || restarted_regex.match(line))
|
557
|
+
activity_started = true
|
558
|
+
pid = activity_start_match[:pid]
|
559
|
+
pid_regex = Regexp.new "\\( *#{pid}\\): "
|
560
|
+
puts "--- activity PID=#{pid}"
|
561
|
+
end
|
562
|
+
if activity_started && (line =~ pid_regex || line =~ related_regex)
|
563
|
+
puts "#{Time.now.strftime('%Y%m%d %H%M%S.%6N')} #{line}"
|
564
|
+
end
|
565
|
+
end
|
566
|
+
puts '--- logcat closed'
|
567
|
+
end
|
568
|
+
end
|
569
|
+
|
530
570
|
# Methods
|
531
571
|
|
532
572
|
def sdk_level
|
@@ -717,17 +757,20 @@ def update_scripts
|
|
717
757
|
return nil
|
718
758
|
end
|
719
759
|
|
760
|
+
def app_running?
|
761
|
+
`adb shell ps | egrep -e " #{package}\r$"`.size > 0
|
762
|
+
end
|
763
|
+
|
720
764
|
def start_app
|
721
765
|
`adb shell am start -a android.intent.action.MAIN -n #{package}/.#{main_activity}`
|
722
766
|
end
|
723
767
|
|
724
768
|
# Triggers reload of updated scripts and restart of the current activity
|
725
769
|
def reload_scripts(scripts)
|
726
|
-
scripts.
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
end
|
770
|
+
s = scripts.map{|s| s.gsub(/[&;]/){|m| "&#{m[0]}"}}.join(';')
|
771
|
+
cmd = %Q{adb shell am broadcast -a android.intent.action.VIEW -e reload "#{s}"}
|
772
|
+
puts cmd
|
773
|
+
system cmd
|
731
774
|
end
|
732
775
|
|
733
776
|
def stop_app
|
@@ -60,11 +60,24 @@ public class THE_RUBOTO_CLASS THE_ACTION THE_ANDROID_CLASS {
|
|
60
60
|
}
|
61
61
|
}
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
public void onDestroy() {
|
64
|
+
if (ScriptLoader.isCalledFromJRuby()) {
|
65
|
+
super.onDestroy();
|
66
|
+
return;
|
67
|
+
}
|
68
|
+
if (!JRubyAdapter.isInitialized()) {
|
69
|
+
Log.i("Method called before JRuby runtime was initialized: RubotoActivity#onDestroy");
|
70
|
+
super.onDestroy();
|
71
|
+
return;
|
72
|
+
}
|
73
|
+
String rubyClassName = scriptInfo.getRubyClassName();
|
74
|
+
if (rubyClassName == null) {
|
75
|
+
super.onDestroy();
|
76
|
+
return;
|
77
|
+
}
|
78
|
+
ScriptLoader.callOnDestroy(this);
|
66
79
|
}
|
67
|
-
|
80
|
+
|
68
81
|
|
69
82
|
/****************************************************************************************
|
70
83
|
*
|
@@ -86,6 +86,24 @@ public class THE_RUBOTO_CLASS THE_ACTION THE_ANDROID_CLASS {
|
|
86
86
|
}
|
87
87
|
}
|
88
88
|
|
89
|
+
public void onDestroy() {
|
90
|
+
if (ScriptLoader.isCalledFromJRuby()) {
|
91
|
+
super.onDestroy();
|
92
|
+
return;
|
93
|
+
}
|
94
|
+
if (!JRubyAdapter.isInitialized()) {
|
95
|
+
Log.i("Method called before JRuby runtime was initialized: RubotoActivity#onDestroy");
|
96
|
+
super.onDestroy();
|
97
|
+
return;
|
98
|
+
}
|
99
|
+
String rubyClassName = scriptInfo.getRubyClassName();
|
100
|
+
if (rubyClassName == null) {
|
101
|
+
super.onDestroy();
|
102
|
+
return;
|
103
|
+
}
|
104
|
+
ScriptLoader.callOnDestroy(this);
|
105
|
+
}
|
106
|
+
|
89
107
|
|
90
108
|
/****************************************************************************************
|
91
109
|
*
|
@@ -35,7 +35,7 @@ public class EntryPointActivity extends org.ruboto.RubotoActivity {
|
|
35
35
|
// The Intent to to call when done. Defaults to calling this Activity again.
|
36
36
|
// Override to change.
|
37
37
|
protected Intent futureIntent() {
|
38
|
-
if (getIntent().getAction().equals(Intent.
|
38
|
+
if (!getIntent().getAction().equals(Intent.ACTION_VIEW)) {
|
39
39
|
return new Intent(getIntent()).setAction(Intent.ACTION_VIEW);
|
40
40
|
} else {
|
41
41
|
return getIntent();
|
@@ -272,6 +272,8 @@ public class JRubyAdapter {
|
|
272
272
|
addLoadPath(scriptsDirName(appContext));
|
273
273
|
put("$package_name", appContext.getPackageName());
|
274
274
|
|
275
|
+
runScriptlet("::RUBOTO_JAVA_PROXIES = {}");
|
276
|
+
|
275
277
|
initialized = true;
|
276
278
|
} catch (ClassNotFoundException e) {
|
277
279
|
handleInitException(e);
|
@@ -353,7 +355,7 @@ public class JRubyAdapter {
|
|
353
355
|
// FIXME(uwe): Remove when we stop supporting Ruby 1.8
|
354
356
|
@Deprecated public static boolean isRubyOneNine() {
|
355
357
|
String rv = ((String)get("RUBY_VERSION"));
|
356
|
-
return rv.startsWith("2.0.") || rv.startsWith("1.9.");
|
358
|
+
return rv.startsWith("2.1.") || rv.startsWith("2.0.") || rv.startsWith("1.9.");
|
357
359
|
}
|
358
360
|
|
359
361
|
static void printStackTrace(Throwable t) {
|
@@ -1,6 +1,7 @@
|
|
1
1
|
package org.ruboto;
|
2
2
|
|
3
3
|
import java.io.IOException;
|
4
|
+
import java.util.Map;
|
4
5
|
|
5
6
|
import android.app.ProgressDialog;
|
6
7
|
import android.content.Context;
|
@@ -12,7 +13,7 @@ public class ScriptLoader {
|
|
12
13
|
*/
|
13
14
|
public static boolean isCalledFromJRuby() {
|
14
15
|
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
|
15
|
-
int maxLookBack = Math.min(
|
16
|
+
int maxLookBack = Math.min(8, stackTraceElements.length);
|
16
17
|
for(int i = 0; i < maxLookBack ; i++){
|
17
18
|
if (stackTraceElements[i].getClassName().startsWith("org.jruby.javasupport.JavaMethod")) {
|
18
19
|
return true;
|
@@ -52,7 +53,6 @@ public class ScriptLoader {
|
|
52
53
|
JRubyAdapter.put("$java_instance", component);
|
53
54
|
rubyClass = JRubyAdapter.runScriptlet("class << $java_instance; self; end");
|
54
55
|
} else if (JRubyAdapter.isRubyOneNine()) {
|
55
|
-
JRubyAdapter.runScriptlet("Java::" + component.getClass().getName() + ".__persistent__ = true");
|
56
56
|
rubyClass = JRubyAdapter.runRubyMethod(component, "singleton_class");
|
57
57
|
} else {
|
58
58
|
throw new RuntimeException("Unknown Ruby version: " + JRubyAdapter.get("RUBY_VERSION"));
|
@@ -67,7 +67,6 @@ public class ScriptLoader {
|
|
67
67
|
Log.d("Script contains class definition");
|
68
68
|
if (rubyClass == null && hasBackingJavaClass) {
|
69
69
|
Log.d("Script has separate Java class");
|
70
|
-
JRubyAdapter.runScriptlet("Java::" + component.getClass().getName() + ".__persistent__ = true");
|
71
70
|
rubyClass = JRubyAdapter.runScriptlet("Java::" + component.getClass().getName());
|
72
71
|
}
|
73
72
|
Log.d("Set class: " + rubyClass);
|
@@ -116,16 +115,40 @@ public class ScriptLoader {
|
|
116
115
|
}
|
117
116
|
|
118
117
|
public static final void callOnCreate(final RubotoComponent component, Object... args) {
|
118
|
+
persistObjectProxy(component);
|
119
119
|
if (component instanceof android.content.Context) {
|
120
120
|
Log.d("Call onCreate on: " + component.getScriptInfo().getRubyInstance());
|
121
121
|
// FIXME(uwe): Simplify when we stop support for snake case aliasing interface callback methods.
|
122
122
|
if ((Boolean)JRubyAdapter.runScriptlet(component.getScriptInfo().getRubyClassName() + ".instance_methods(false).any?{|m| m.to_sym == :onCreate}")) {
|
123
123
|
JRubyAdapter.runRubyMethod(component.getScriptInfo().getRubyInstance(), "onCreate", args);
|
124
|
-
} else if ((Boolean)JRubyAdapter.runScriptlet(component.getScriptInfo().getRubyClassName() + ".instance_methods(
|
124
|
+
} else if ((Boolean)JRubyAdapter.runScriptlet(component.getScriptInfo().getRubyClassName() + ".instance_methods(true).any?{|m| m.to_sym == :on_create}")) {
|
125
125
|
JRubyAdapter.runRubyMethod(component.getScriptInfo().getRubyInstance(), "on_create", args);
|
126
|
+
} else {
|
127
|
+
JRubyAdapter.runRubyMethod(component.getScriptInfo().getRubyInstance(), "onCreate", args);
|
126
128
|
}
|
127
129
|
// EMXIF
|
128
130
|
}
|
129
131
|
}
|
130
132
|
|
133
|
+
public static final void callOnDestroy(final RubotoComponent component) {
|
134
|
+
String rubyClassName = component.getScriptInfo().getRubyClassName();
|
135
|
+
if ((Boolean)JRubyAdapter.runScriptlet(rubyClassName + ".instance_methods(false).any?{|m| m.to_sym == :onDestroy}")) {
|
136
|
+
JRubyAdapter.runRubyMethod(component.getScriptInfo().getRubyInstance(), "onDestroy");
|
137
|
+
} else if ((Boolean)JRubyAdapter.runScriptlet(rubyClassName + ".instance_methods(true).any?{|m| m.to_sym == :on_destroy}")) {
|
138
|
+
JRubyAdapter.runRubyMethod(component.getScriptInfo().getRubyInstance(), "on_destroy");
|
139
|
+
} else {
|
140
|
+
JRubyAdapter.runRubyMethod(component.getScriptInfo().getRubyInstance(), "onDestroy");
|
141
|
+
}
|
142
|
+
releaseObjectProxy(component);
|
143
|
+
}
|
144
|
+
|
145
|
+
private static void persistObjectProxy(RubotoComponent component) {
|
146
|
+
JRubyAdapter.runScriptlet("Java::" + component.getClass().getName() + ".__persistent__ = true");
|
147
|
+
((Map)JRubyAdapter.get("RUBOTO_JAVA_PROXIES")).put(component.getScriptInfo().getRubyInstance(), component.getScriptInfo().getRubyInstance());
|
148
|
+
}
|
149
|
+
|
150
|
+
private static void releaseObjectProxy(RubotoComponent component) {
|
151
|
+
((Map)JRubyAdapter.get("RUBOTO_JAVA_PROXIES")).remove(component.getScriptInfo().getRubyInstance());
|
152
|
+
}
|
153
|
+
|
131
154
|
}
|
@@ -62,8 +62,9 @@ module Ruboto
|
|
62
62
|
raise "Unknown options: #{options}" unless options.empty?
|
63
63
|
|
64
64
|
if class_name.nil? && block_given?
|
65
|
+
src_desc = source_descriptor(block)
|
65
66
|
class_name =
|
66
|
-
"#{java_class.name.split('::').last}_#{
|
67
|
+
"#{java_class.name.split('::').last}_#{src_desc[0].split('/').last.gsub(/[.-]+/, '_')}_#{src_desc[1]}"
|
67
68
|
end
|
68
69
|
|
69
70
|
class_name = class_name.to_s
|
@@ -85,8 +86,8 @@ module Ruboto
|
|
85
86
|
|
86
87
|
private
|
87
88
|
|
88
|
-
def source_descriptor(
|
89
|
-
if md = /^#<Proc:0x[0-9A-Fa-f]+@(.+):(\d+)(?: \(lambda\))?>$/.match(
|
89
|
+
def source_descriptor(src_proc)
|
90
|
+
if (md = /^#<Proc:0x[0-9A-Fa-f-]+@(.+):(\d+)(?: \(lambda\))?>$/.match(src_proc.inspect))
|
90
91
|
filename, line = md.captures
|
91
92
|
return filename, line.to_i
|
92
93
|
end
|
@@ -1,14 +1,16 @@
|
|
1
|
+
require 'ruboto/activity'
|
2
|
+
|
1
3
|
module Ruboto::Activity::Reload
|
2
4
|
import org.ruboto.Log
|
3
5
|
|
4
6
|
def onResume
|
5
|
-
Log.d
|
7
|
+
Log.d 'Ruboto::Activity::Reload onResume'
|
6
8
|
super
|
7
9
|
|
8
10
|
@ruboto_activity_reload_receiver = ReloadReceiver.new(self)
|
9
11
|
filter = android.content.IntentFilter.new(android.content.Intent::ACTION_VIEW)
|
10
12
|
registerReceiver(@ruboto_activity_reload_receiver, filter)
|
11
|
-
Log.d
|
13
|
+
Log.d 'Ruboto::Activity::Reload registered reload receiver'
|
12
14
|
rescue Exception
|
13
15
|
Log.e "Exception registering reload listener: #{$!.message}"
|
14
16
|
Log.e $!.backtrace.join("\n")
|
@@ -18,7 +20,7 @@ module Ruboto::Activity::Reload
|
|
18
20
|
super
|
19
21
|
unregisterReceiver(@ruboto_activity_reload_receiver)
|
20
22
|
@ruboto_activity_reload_receiver = nil
|
21
|
-
Log.d
|
23
|
+
Log.d 'Ruboto::Activity::Reload unregistered reload receiver'
|
22
24
|
rescue Exception
|
23
25
|
Log.e "Exception unregistering reload listener: #{$!.message}"
|
24
26
|
Log.e $!.backtrace.join("\n")
|
@@ -38,17 +40,20 @@ module Ruboto::Activity::Reload
|
|
38
40
|
# but have not found a way to do that.
|
39
41
|
def onReceive(context, reload_intent)
|
40
42
|
Log.d "Got reload intent: #{reload_intent.inspect}"
|
41
|
-
|
42
|
-
if
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
43
|
+
file_string = reload_intent.get_string_extra('reload')
|
44
|
+
if file_string
|
45
|
+
files = file_string.split(/(?<!&);/).map { |f| f.gsub(/&(.)/) { |m| m[1] } }
|
46
|
+
files.each do |file|
|
47
|
+
Log.d "load file: #{file.inspect}"
|
48
|
+
load file
|
49
|
+
end
|
47
50
|
Log.d 'restart activity'
|
48
|
-
if @activity.intent.action == android.content.Intent::ACTION_MAIN
|
49
|
-
|
51
|
+
if @activity.intent.action == android.content.Intent::ACTION_MAIN ||
|
52
|
+
@activity.intent.action == android.hardware.usb.UsbManager::ACTION_USB_DEVICE_ATTACHED
|
53
|
+
restart_intent = android.content.Intent.new(@activity.intent).
|
54
|
+
setAction(android.content.Intent::ACTION_VIEW)
|
50
55
|
else
|
51
|
-
|
56
|
+
restart_intent = @activity.intent
|
52
57
|
end
|
53
58
|
@activity.startActivity(restart_intent)
|
54
59
|
@activity.finish
|
data/assets/src/ruboto/widget.rb
CHANGED
@@ -109,7 +109,7 @@ def ruboto_import_widget(class_name, package_name='android.widget')
|
|
109
109
|
|
110
110
|
return unless klass
|
111
111
|
|
112
|
-
|
112
|
+
method_str = "
|
113
113
|
def #{(class_name.to_s.gsub(/([A-Z])/) { '_' + $1.downcase })[1..-1]}(params={})
|
114
114
|
if force_style = params.delete(:default_style)
|
115
115
|
rv = #{class_name}.new(self, nil, force_style)
|
@@ -134,6 +134,13 @@ def ruboto_import_widget(class_name, package_name='android.widget')
|
|
134
134
|
rv
|
135
135
|
end
|
136
136
|
"
|
137
|
+
RubotoActivity.class_eval method_str
|
138
|
+
|
139
|
+
# FIXME(uwe): Remove condition when we stop support for api level < 11
|
140
|
+
if android.os.Build::VERSION::SDK_INT >= 11
|
141
|
+
android.app.Fragment.class_eval method_str.gsub('self', 'activity')
|
142
|
+
end
|
143
|
+
# EMXIF
|
137
144
|
|
138
145
|
setup_list_view if class_name == :ListView
|
139
146
|
setup_spinner if class_name == :Spinner
|
@@ -166,14 +173,12 @@ def setup_image_button
|
|
166
173
|
end
|
167
174
|
|
168
175
|
def setup_list_view
|
169
|
-
|
170
|
-
|
176
|
+
android.widget.ListView.__persistent__ = true
|
177
|
+
android.widget.ListView.class_eval do
|
171
178
|
def configure(context, params = {})
|
172
179
|
if (list = params.delete(:list))
|
173
|
-
@adapter_list = Java::java.util.ArrayList.new
|
174
|
-
@adapter_list.addAll(list)
|
175
180
|
item_layout = params.delete(:item_layout) || R::layout::simple_list_item_1
|
176
|
-
params[:adapter] =
|
181
|
+
params[:adapter] = android.widget.ArrayAdapter.new(context, item_layout, list)
|
177
182
|
end
|
178
183
|
super(context, params)
|
179
184
|
end
|
@@ -188,19 +193,14 @@ def setup_list_view
|
|
188
193
|
end
|
189
194
|
|
190
195
|
def setup_spinner
|
191
|
-
|
192
|
-
|
193
|
-
attr_reader :adapter, :adapter_list
|
194
|
-
|
196
|
+
android.widget.Spinner.__persistent__ = true
|
197
|
+
android.widget.Spinner.class_eval do
|
195
198
|
def configure(context, params = {})
|
196
|
-
if params.
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
@adapter.setDropDownViewResource(params.delete(:dropdown_layout) || R::layout::simple_spinner_dropdown_item)
|
202
|
-
setAdapter @adapter
|
203
|
-
params.delete :list
|
199
|
+
if (list = params.delete(:list))
|
200
|
+
item_layout = params.delete(:item_layout)
|
201
|
+
params[:adapter] = android.widget.ArrayAdapter.new(context, item_layout || R::layout::simple_spinner_item, list)
|
202
|
+
dropdown_layout = params.delete(:dropdown_layout)
|
203
|
+
params[:adapter].setDropDownViewResource(dropdown_layout) if dropdown_layout
|
204
204
|
end
|
205
205
|
super(context, params)
|
206
206
|
end
|