我已經被賦予向Appcelerator Studio中編寫的移動應用添加新功能的任務。應用程序的所有者請求使用Appcelerator的API不易支持的功能,但它很容易通過Android和iOS中的本機代碼支持。我的任務是將原生Android和iOS代碼集成到Appcelerator代碼中。在Appcelerator中創建工作Android模塊
我正在努力整合Android代碼。我按照此頁上的說明操作:https://wiki.appcelerator.org/display/guides2/Android+Module+Quick+Start,但當我通過USB電纜在Android設備上運行應用程序時,該應用程序會引發錯誤。下面是在Android設備上出現的錯誤:
如在上述網頁所提到的,別人問起一月發生同樣的事情,但答案尚未發佈那裏呢。
我在做什麼錯?
這是我的代碼爲Hello應用程序。
tiapp.xml:
<?xml version="1.0" encoding="UTF-8"?>
<ti:app xmlns:ti="http://ti.appcelerator.org">
<id>com.example.hello</id>
<name>hello</name>
<version>1.0</version>
<publisher>user</publisher>
<url/>
<description/>
<copyright>2016 by user</copyright>
<icon>appicon.png</icon>
<fullscreen>false</fullscreen>
<navbar-hidden>false</navbar-hidden>
<analytics>true</analytics>
<guid>877d5eaf-034e-4df6-9fff-a2de5a005994</guid>
<property name="ti.ui.defaultunit" type="string">dp</property>
<ios>
<enable-launch-screen-storyboard>true</enable-launch-screen-storyboard>
<plist>
<dict>
<key>UISupportedInterfaceOrientations~iphone</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIRequiresPersistentWiFi</key>
<false/>
<key>UIPrerenderedIcon</key>
<false/>
<key>UIStatusBarHidden</key>
<false/>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleDefault</string>
</dict>
</plist>
</ios>
<android xmlns:android="http://schemas.android.com/apk/res/android"/>
<mobileweb>
<precache/>
<splash>
<enabled>true</enabled>
<inline-css-images>true</inline-css-images>
</splash>
<theme>default</theme>
</mobileweb>
<modules>
<module platform="commonjs">ti.cloud</module>
<!-- This is the relevant part. -->
<module platform="android">com.example.test</module>
</modules>
<deployment-targets>
<target device="android">true</target>
<target device="ipad">true</target>
<target device="iphone">true</target>
<target device="mobileweb">true</target>
<target device="windows">false</target>
</deployment-targets>
<sdk-version>5.3.0.GA</sdk-version>
<plugins>
<plugin version="1.0">ti.alloy</plugin>
</plugins>
<!-- Various properties associated with oauth. -->
</ti:app>
alloy.js:
var test = require('com.example.test');
Ti.API.info("module is => " + test);
Ti.API.info("module example() method returns => " + test.example());
Ti.API.info("module exampleProp is => " + test.exampleProp);
test.exampleProp = "This is a test value";
index.js:
$.index.open();
$.test.exampleProp = 'foobar';
// This breaks the application.
//Ti.API.info('exampleProp: ' + $.test.getExampleProp());
// This works.
Ti.API.info('exampleProp: ' + $.test.exampleProp);
// This breaks the application
//Ti.API.info('foo: ' + $.test.getFoo());
// This breaks the application.
//Test.createExample({message: "hello world"});
var view = test.createExample({
color: 'blue',
height: 50,
width: 50
});
// This breaks the application.
//win.add(view);
// This has no effect.
$.index.add(view);
INDEX.XML:
<Alloy>
<Window class="container">
<Module id="test" module="com.example.test" method="createView" height="50" width="50" color="red"/>
</Window>
</Alloy>
下面是測試模塊代碼:
ExampleProxy.java:
/**
* This file was auto-generated by the Titanium Module SDK helper for Android
* Appcelerator Titanium Mobile
* Copyright (c) 2009-2010 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*
*/
package com.example.test;
import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.KrollProxy;
import org.appcelerator.kroll.annotations.Kroll;
import org.appcelerator.titanium.TiC;
import org.appcelerator.titanium.util.Log;
import org.appcelerator.titanium.util.TiConfig;
import org.appcelerator.titanium.util.TiConvert;
import org.appcelerator.titanium.proxy.TiViewProxy;
import org.appcelerator.titanium.view.TiCompositeLayout;
import org.appcelerator.titanium.view.TiCompositeLayout.LayoutArrangement;
import org.appcelerator.titanium.view.TiUIView;
import android.app.Activity;
import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.annotations.Kroll;
import org.appcelerator.kroll.common.AsyncResult;
import org.appcelerator.kroll.common.TiMessenger;
import org.appcelerator.titanium.TiApplication;
import org.appcelerator.titanium.TiC;
import org.appcelerator.titanium.util.TiConvert;
import org.appcelerator.titanium.proxy.TiViewProxy;
import org.appcelerator.titanium.view.TiCompositeLayout;
import org.appcelerator.titanium.view.TiCompositeLayout.LayoutArrangement;
import org.appcelerator.titanium.view.TiUIView;
import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import android.view.View;
// This proxy can be created by calling Test.createExample({message: "hello world"})
@Kroll.proxy(creatableInModule=TestModule.class)
public class ExampleProxy extends TiViewProxy
{
private static final int MSG_SET_COLOR = 70000;
private static final String PROPERTY_COLOR = "color";
private class ExampleView extends TiUIView
{
public ExampleView(TiViewProxy proxy) {
super(proxy);
LayoutArrangement arrangement = LayoutArrangement.DEFAULT;
if (proxy.hasProperty(TiC.PROPERTY_LAYOUT)) {
String layoutProperty = TiConvert.toString(proxy.getProperty(TiC.PROPERTY_LAYOUT));
if (layoutProperty.equals(TiC.LAYOUT_HORIZONTAL)) {
arrangement = LayoutArrangement.HORIZONTAL;
} else if (layoutProperty.equals(TiC.LAYOUT_VERTICAL)) {
arrangement = LayoutArrangement.VERTICAL;
}
}
setNativeView(new TiCompositeLayout(proxy.getActivity(), arrangement));
}
@Override
public void processProperties(KrollDict props)
{
super.processProperties(props);
// Check if the color is specified when the view was created
if (props.containsKey(PROPERTY_COLOR)) {
View square = (View)getNativeView();
square.setBackgroundColor(TiConvert.toColor(props, PROPERTY_COLOR));
square.invalidate();
}
}
// Setter method called by the proxy when the 'color' property is set.
public void setColor(String color)
{
// Use the TiConvert method to get the values from the arguments
int newColor = TiConvert.toColor(color);
View square = (View)getNativeView();
square.setBackgroundColor(newColor);
}
}
@Override
public TiUIView createView(Activity activity)
{
TiUIView view = new ExampleView(this);
view.getLayoutParams().autoFillsHeight = true;
view.getLayoutParams().autoFillsWidth = true;
return view;
}
@Kroll.setProperty(retain=false)
public void setColor(final String color)
{
// Get the view object from the proxy and set the color
if (view != null) {
if (!TiApplication.isUIThread()) {
// If we are not on the UI thread, need to use a message to set the color
TiMessenger.sendBlockingMainMessage(new Handler(TiMessenger.getMainMessenger().getLooper(), new Handler.Callback() {
public boolean handleMessage(Message msg) {
switch (msg.what) {
case MSG_SET_COLOR: {
AsyncResult result = (AsyncResult) msg.obj;
ExampleView fooView = (ExampleView)view;
fooView.setColor(color);
result.setResult(null);
return true;
}
}
return false;
}
}).obtainMessage(MSG_SET_COLOR), color);
} else {
ExampleView fooView = (ExampleView)view;
fooView.setColor(color);
}
}
// Updates the property on the JavaScript proxy object
setProperty("color", color, true);
}
}
TestModule.java:
/**
* This file was auto-generated by the Titanium Module SDK helper for Android
* Appcelerator Titanium Mobile
* Copyright (c) 2009-2010 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*
*/
package com.example.test;
import org.appcelerator.kroll.KrollModule;
import org.appcelerator.kroll.annotations.Kroll;
import org.appcelerator.titanium.TiApplication;
import org.appcelerator.kroll.common.Log;
import org.appcelerator.kroll.common.TiConfig;
@Kroll.module(name="Test", id="com.example.test", propertyAccessors = {"exampleProp"})
public class TestModule extends KrollModule
{
// Standard Debugging variables
private static final String LCAT = "TestModule";
private static final boolean DBG = TiConfig.LOGD;
private String foo;
// You can define constants with @Kroll.constant, for example:
// @Kroll.constant public static final String EXTERNAL_NAME = value;
public TestModule()
{
super();
}
@Kroll.onAppCreate
public static void onAppCreate(TiApplication app)
{
Log.d(LCAT, "inside onAppCreate");
// put module init code that needs to run when the application is created
}
// Methods
@Kroll.method
public String example()
{
Log.d(LCAT, "example called");
return "hello world";
}
// Properties
@Kroll.getProperty
public String getExampleProp()
{
Log.d(LCAT, "get example property");
return foo;
}
@Kroll.setProperty
public void setExampleProp(String value) {
Log.d(LCAT, "In Module - the new value for exampleProp:" + foo);
foo = value;
}
@Kroll.method
public String getFoo() {
return foo;
}
}
如果你看一下我張貼index.js的代碼,你的建議與意見出現行了,「這個工程「。訪問屬性很棒,但我必須訪問方法來完成我需要用我的Android代碼完成的操作。我如何使這些方法起作用? – user3188777