Today (which means Sunday, and in Stockholm is has been snowing!), I have been working on using Java Proxy as a way to dynamically implement interfaces in JavaScript. My need for this arose from wanting to implement a custom ListAdapter for use with a ListView (see previous post for some more background to the issues involved). It would be possible to implement everything that is needed in Java, but it is much more fun to stretch the limits of what is possible to do in JavaScript. And it is a great learning experience.
The interactive web based DroidScript editor has been invaluable when experimenting with JavaScript on Android. I have my phone next to the computer, edit and run code from Firefox on the computer, and interact with the result on the phone. This is a quite nice way to work. Error handling still leaves much more to wish for in DroidScript. It is sometimes tricky to find errors, and hooking up with a USB cable and using logcat is a big help to track down exceptions. Good, readable error reporting is an important area to improve upon. But, since you typically evaluate small pieces of code when developing incrementally, it is usually easy to spot errors.
The following is a complete example that can run from the DroidScript editor. Make sure the DroidScript server is running on the device, paste the code into the editor, select it, and then click "Run as Activity".
function onCreate(bundle)
{
var lang = Packages.java.lang;
var android = Packages.android;
var widget = Packages.android.widget;
var Typeface = Packages.android.graphics.Typeface;
var Color = Packages.android.graphics.Color;
var listView = new widget.ListView(Activity);
var fruits = ["Lemon", "Peach", "Plum"];
listView.setAdapter(createListViewArrayAdapter(
fruits,
function(position, convertView) {
var view = convertView;
if (null == convertView) {
view = new widget.TextView(Activity);
view.setPadding(25, 15, 25, 15);
var font = Typeface.create(
Typeface.SANS_SERIF,
Typeface.BOLD);
view.setTypeface(font);
view.setTextSize(26);
view.setBackgroundColor(Color.rgb(0, 0, 64));
view.setTextColor(Color.rgb(255, 255, 255));
// It is also possible to put actions on list items
//view.setOnClickListener(function () {
// view.setText("You Clicked Me!"); })
}
view.setText(fruits[position]);
return view; }));
listView.setOnItemClickListener(function(parent, view, position, id) {
showMessage("You picked: " + fruits[position]); });
Activity.setContentView(listView);
}
// Display a Toast on the device
function showMessage(message)
{
var Toast = Packages.android.widget.Toast;
Toast.makeText(
Activity,
message,
Toast.LENGTH_LONG).show();
}
// Convert a Java array to a JavaScript array
function javaArrayToJsArray(javaArray)
{
var jsArray = [];
for (i = 0; i < javaArray.length; ++i) {
jsArray[i] = javaArray[i];
}
return jsArray;
}
// Create an instance of a Java interface
// javaInterface - the interface type
// handler - object that will be sent messages to the instance
function createInstance(javaInterface, handler)
{
var lang = Packages.java.lang;
var interfaces = lang.reflect.Array.newInstance(lang.Class, 1);
interfaces[0] = javaInterface;
var obj = lang.reflect.Proxy.newProxyInstance(
lang.ClassLoader.getSystemClassLoader(),
interfaces,
// Note, args is a Java array.
function(proxy, method, args) {
// Convert Java array to JavaScript array
return handler[method.getName()].apply(
null,
javaArrayToJsArray(args));
});
return obj;
}
// Creates a custom ListAdapter
// items - a JavaScript array
// viewFun - a function called to handle the creation
// of views for the elements in the list
function createListViewArrayAdapter(items, viewFun)
{
var lang = Packages.java.lang;
var widget = Packages.android.widget;
var observer;
var handler = {
areAllItemsEnabled : function() {
return lang.Boolean.TRUE; },
isEnabled : function(position) {
return lang.Boolean.TRUE; },
getCount : function() {
return lang.Integer.valueOf(items.length); },
getItem : function(position) {
return items[position]; },
getItemId : function(position) {
return lang.Long.valueOf(position); },
getItemViewType : function(position) {
return lang.Integer.valueOf(0); },
getView : function(position, convertView, parent) {
return viewFun(position, convertView); },
getViewTypeCount : function(position) {
return lang.Integer.valueOf(1); },
hasStableIds : function(position) {
return true; },
isEmpty : function(position) {
return 0 == items.length; },
// We can only have one observer!
registerDataSetObserver : function(theObserver) {
observer = theObserver; },
unregisterDataSetObserver : function(theObserver) {
observer = null; },
};
return createInstance(Packages.android.widget.ListAdapter, handler);
}
When I bought my computer and I didn´t know how to use java graphics, so I decided looking for information in a webside and I found an useful information that helped me a lot.. Now I am interested in to do the best investment and I found a webside very useful and interesting called costa rica investment opportunities , I think it´s a very wonderful site.
ReplyDeleteJavaScript is a good program and very easy to use. I don´t like a complex program. I prefer javascript because i consider it like a device very eficient and it have a good quality.
ReplyDeleteI always looking for the quality that is why i prefer to buy viagra because i always have a great result in my sexual life.