Back

Titanium 进阶: 安卓 module中的各种概念, 与Activity 的lifecycle

发布时间: 2016-01-07 03:08:00

refer to:  http://docs.appcelerator.com/platform/latest/#!/guide/Android_Module_Architecture

小概念

Proxy: A base class that represents the native binding between your JavaScript code and native code,  沟通 js code 与native code的桥梁

Module: 一种特殊的proxy, 带有namespace (require 'a.b.c') 
A special type of Proxy that describes a specific API set or namespace

ViewProxy: 一种专门渲染view的proxy (A specialized Proxy that knows how to render Views)

View: Ti可以渲染的视图( The visual representation of a UI component which Titanium can render)

Module 只能有一个, view, proxy, view proxy 的个数不做限制。

Module lifecycle 与 Activity lifecycle

Module lifecyle:

Use the @Kroll.onAppCreate annotation to declare a method to be called when the application object is created. This is optional and is only required if you have any application specific initialization, such as starting up a service that is required by the module.

The app create method is called during application startup. It is only called once, before your module is actually loaded.

使用 onAppCreate 方法,是个hook 方法,在app启动时, module加载之前运行, 只运行一次。

Activity life cycle:

titanium app中, root activity 就是启动图所在的activity ( splash )

如果第一个UI组件,是个window, 或者tabgroup的话,那么该 root activity 不是所有的 event都会被触发。

所有的windows 都是heavy weight的。 所以他们有自己的activity . 

下面的代码例子,来自于:https://github.com/appcelerator-modules/ti.moddevguide/blob/master/android/src/ti/moddevguide/ModdevguideModule.java#L72

官方文档把它放在了proxy中, github(上面)的代码放到了module中。经过测试,效果是一样的。

@Kroll.module(name="Moddevguide", id="ti.moddevguide")
public class ModdevguideModule extends KrollModule
{
	@Kroll.onAppCreate
	public static void onAppCreate(TiApplication app) 
	{
		// This method is called during application startup. It is only called once and
		// is called before your module is actually loaded. Use this method to perform
		// process specific initialization -- for example, starting a service that is 
		// required by the module.
		
		Log.d(LCAT, "[MODULE LIFECYCLE EVENT] onAppCreate notification");
	}
	
	public ModdevguideModule() 
	{

	}
	
	// Lifecycle
	// NOTES:
	//
	// 1. Modules are created in the root context
	// 2. Using navBarHidden (or fullscreen or modal) causes the window, when opened, to run in a new Android Activity. 
	// 3. The root context/activity will be stopped when a new activity is launched
	// 4. Lifecycle notifications will NOT be received while the root activity is stopped.

	@Override
	public void onStart(Activity activity) 
	{
		// This method is called when the module is loaded and the root context is started
		
		Log.d(LCAT, "[MODULE LIFECYCLE EVENT] start");
		
		super.onStart(activity);
	}
	
	@Override
	public void onStop(Activity activity) 
	{
		// This method is called when the root context is stopped 
		
		Log.d(LCAT, "[MODULE LIFECYCLE EVENT] stop");
		
		super.onStop(activity);
	}
	
	@Override
	public void onPause(Activity activity) 
	{
		// This method is called when the root context is being suspended
		
		Log.d(LCAT, "[MODULE LIFECYCLE EVENT] pause");
		
		super.onPause(activity);
	}
	
	@Override
	public void onResume(Activity activity) 
	{		
		// This method is called when the root context is being resumed
		
		Log.d(LCAT, "[MODULE LIFECYCLE EVENT] resume");	
		
		super.onResume(activity);
	}
	
	@Override
	public void onDestroy(Activity activity) 
	{
		// This method is called when the root context is being destroyed
		
		Log.d(LCAT, "[MODULE LIFECYCLE EVENT] destroy");
		
		super.onDestroy(activity);
	}
	

获取到当前的activity 

TiApplication appContext = TiApplication.getInstance();
Activity activity = appContext.getCurrentActivity();

Activity Lifecycle Events

Starting with Titanium SDK 4.0.0, a proxy can respond to activity lifecycle events by overriding the activity lifecycle callbacks, then in the JavaScript application, assign either a Window or TabGroup object to the proxy's lifecycleContainer property when creating the module proxy to monitor the lifecycle events of that object to trigger the module proxy's lifecycle events. 

在Ti 4.0开始, 一个proxy就可以对应 activity的lifecycle.  然后,在titanium项目中,新建一个 windows/tab group, 然后把proxy 与之进行绑定, 就可以了。

First, in the module proxy, override the activity lifecycle callbacks you want to respond to, such as onCreate, onStart, onRestart, onResume, onPause, onStop or onDestroy.

下面,就是一个例子,在 Proxy 中,override各种 activity callbacks.

// ExampleProxy.java
    @Override
    public void onResume(Activity activity) {
        Log.d(LCAT, "onResume called");
        loadState();
    }
    @Override
    public void onPause(Activity activity) {
        Log.d(LCAT, "onPause called");
        saveState();
    }

Then, in the JavaScript application, when you create the module proxy, assign its lifecycleContainer property to either a Window or TabGroup object to listen for that object's lifecycle events to trigger the module proxy's activity lifecycle callbacks.

然后,按照下面的方式,把该 proxy 放到某个window / tab group里面。

app.js
var win = Ti.UI.createWindow();
var foo = require('com.appc.foo');
var fooProxy = foo.createExample({lifecycleContainer: win});
win.open();

View Proxy 和 View

To display UI elements with a module, create both a View Proxy and a View. A View Proxy is a special Proxy that is used for Views — objects which interact with the UI to draw things on the screen. The View Proxy is for exposing methods and properties of the view to JavaScript (just as a normal proxy would do), while a View acts as a model listener for the View Proxy. The view implementation is responsible for taking data from the view proxy, and applying it directly to the native View that it exposes.

要通过module显示UI组件,就得同时使用 ViewProxy 和View.
View Proxy 是一种特殊的proxy, 专门给view ( view的定义: objects which interact with the uI to draw things on the screen) 使用。
View proxy 为js 暴露出专门的接口, View 就是 View proxy的 model listener.
view 从 view proxy中获取数据,然后把它传给 native view.

1. View proxy : 务必要实现 createView方法。如下:

package com.example.test;
import org.appcelerator.kroll.annotations.Kroll;
import org.appcelerator.titanium.proxy.TiViewProxy;
@Kroll.proxy(creatableInModule=TestModule.class)
public class FooProxy extends TiViewProxy
{
    @Override
    public TiUIView createView(Activity activity)   // 必须要实现这个
    {
        // Calls the View constructor
        return new FooView(this);   // 这个 FooView 就是个View. 
    }
}

可以在该view proxy中,直接调用 view 这个变量,获取到对应的view: 

FooView fooView = (FooView)view;

2. View: 

A View must extend the TiUIView class. All view class names and file names must have the View suffix. Any class that extends the TiUIView class must implement a constructor and call setNativeView with an instance of a native Android View either in the constructor or in processProperties.

View 必须extend TiUIView, 必须要有 xxView 这样的命名形式。必须要实现一个constructor, 和
必须要在 constructor 或者 processProperties 中,调用 setNativeView

package com.example.test;
 
import org.appcelerator.titanium.view.TiUIView;
import org.appcelerator.titanium.view.TiCompositeLayout;
import org.appcelerator.titanium.view.TiCompositeLayout.LayoutArrangement;
import org.appcelerator.titanium.proxy.TiViewProxy;
import android.view.View;
private class ExampleView extends TiUIView
{
    public ExampleView(TiViewProxy proxy) {
        super(proxy);
        setNativeView(new TiCompositeLayout(proxy.getActivity(), LayoutArrangement.DEFAULT));
    }
}

Back