在java官网下载jdk8,下载地址是http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html,下载后完成安装,在命令行输入下述命令
java -version
输出版本号”java version”和”Java SE Runtime Environment”即说明安装成功。
在官网下载Android Studio(下文简称AS),在本文编写时是3.0版,下载地址是http://www.android-studio.org,下载的是一个dmg包,直接把App拉到Application下即可。
打开AS,会弹出”Android Studio First Run”窗口,点击”Cancel”
接下来会弹出”Android Studio Setup Wizard”窗口,在”Install Type”步骤中选中”Custom”,按需要选中下载部件,建议按默认的来就行,这里的”Android Virtual Device”可以不选(下文会解释),点击”Next”,下一步点击”Finish”。AS就开始下载部件,整个下载过程都比较顺利,等了大约30分钟完成,没有出现某些部件无法下载的情况。
完整的错误提示是”Gradle sync failed: Failed to find target with hash string ‘android-26’”
这里提示的不是SDK platform 26,而是Build Tools revision 26.0.2,直接点击错误提示下面的链接完成下载即可。
编译完成后想用android虚拟设备(AVD)调试,提示”intel HAXM is required to run this AVD. Unknown Error”
经查实,intel HAXM已经安装,目前还没有找到解决方法,决定绕开这个问题,不使用AVD调试程序,这就是为什么上文AS配置时我不选择安装android虚拟设备的原因,解决方案有两个:
打开真机的USB调试,有些机型需要在设置里的系统版本号点击4次开启”开发者选项”,里面才有USB调试的开启按钮。把真机连接PC,在编译App后在Connected Device下选中该设备进行调试。
Genymotion是一款很快的android虚拟机,下载安装后,在Settings - ADB下,选择”Use custom Android SDK tools”并填入sdk路径,该路径可以在AS的Preferences - Apperarance & Behavior - System Settings - Android SDK下看到。
然后开启Genymotion虚拟机,编译项目时就可以在Connected Device下选择该虚拟设备调试了。Genymotion是x86而不是arm框架的,很多应用安装不了,会提示不兼容。
可以通过Genymotion-ARM-Translation把x86转换成arm框架,这个在网上可以下载
针对4.x的安卓版本
打开Genymotion后,直接把Genymotion-ARM-Translation_v1.1.zip直接拉进虚拟机,重启。
针对5.x的安卓版本
打开Genymotion后,把ARM_Translation_Lollipop.zip拉进去,然后使用adb输入命令:
adb shell /system/etc/houdini_patcher.sh
再重启虚拟机。
夜神模拟器有win版和mac版的,时arm框架的,使用起来也十分流畅,一些大型游戏和应用都能安装成功,运行起来也很流畅。
和真机一样,在setting里打开”USB调试”,然后用sdk的adb通过以下命令连接该虚拟机
adb connect 127.0.0.1:62001
就可以通过adb devices
就可以看到这个设备了。
至于这个62001
端口,可以通过以下命令获取
lsof -i tcp:62001
通过上面命令可以看到,占有该端口的进程是VBoxHeadl
,通过下面命令可以在不知道端口时用来查询端口
lsof -i tcp | grep VBoxHeadl
但是若有多个VBoxHeadl进程,就难以辨别哪个时夜神模拟器的。
通过上面的connect之后,就可以用夜神模拟器来调试App了。
ps: 夜神模拟器里也包含adb,mac版在Nox App Player.app/Contents/MacOS/
下,win版在C:\Users\XXX\AppData\Roaming\Nox\bin
下。
Jacob Pan ( jacobpan3g.github.io/cn )
Tab({mContent: mParent: })
构造函数的参数与UILite.Object类一致,其中,mContent的html可以是以下格式:
<span>tab1</span>
<span>tab2</span>
<span>tab3</span>
<div><span class="UILFile"></span></div>
<div>Tab view</div>
<div>Html argument</div>
ps: 上述的传入html或者dom对象,以及dom对象的解析暂未实现,因为这个从dom转换成UIL对象涉及到嵌套解析,这个逻辑比较复杂且容易出错。
另外,mContent还可以是一个js对象
{
tab1: new UILite.File(),
tab2: <p>Hello</p>
}
页面上的tab dom数组
获取当前显示页面的tab。
显示指定tab对应的页面。
切换时,先会保存tab再matTabs
的下标,然后把其它tab的页面隐藏,把指定tab的页面显示出来。
重载了UILite.Container.add(aContent),主要用来添加tab。
添加的tab会转换成dom对象,并加入matTabs
数组中,aContent是UILite.Object子类的话就直接添加到maoContainer
数组中,不是的话会将其生成UILite.Object对象再放进数组中。
var myTab = new UILite.Tab();
myTab.add(new UILite.File(), "tab1");
myTab.add("<p>Hello</p>", "tab1");
myTab.setParent(document.body);
myTab.show();
创建Tab对象后,通过add()
添加tab,并把自己的dom添加到body标签。
var myTab = new UILite.Tab({
mContent: {
tab1: new UILite.File(),
tab2: "<p>Hello</p>",
},
mParent: document.body,
});
myTab.show();
直接通过构造函数添加tab和设置parent,其他与上例一样。
var lastTab = myTab.getCurTab();
myTab.setCurTab("tab2");
Jacob Pan ( jacobpan3g.github.io/cn )
Gallery({mContent: mParent: })
构造函数的参数与UILite.Object类一致,mContent可以是js数组对象
[
new UILite.File(),
<div>hello</div>
]
页面Next按钮的Dom对象
页面Pre按钮的Dom对象
获取当前显示页面的idx
显示指定idx的页面
var myGallery = new UILite.Gallery();
myGallery.add(new UILite.File());
myGallery.add("<div>hello</div>");
myGallery.add(new UILite.Object("<div>world</div>"));
myGallery.setParent(document.body);
myGallery.show();
add()
继承与UILite.Container。
var myGallery = new UILite.Gallery({
mContent: [
new UILite.File(),
"<div>hello</div>",
new UILite.Object("<div>world</div>"),
],
mParent: document.body,
});
myGallery.show();
var idx = myGallery.getCurIdx();
myGallery.setCurIdx(2);
Jacob Pan ( jacobpan3g.github.io/cn )
Gallery({mContent: mParent: })
构造函数的参数与UILite.Object类一致,mContent可以是js数组对象
[
new UILite.File(),
<div>hello</div>
]
页面Next按钮的Dom对象
页面Pre按钮的Dom对象
获取当前显示页面的idx
显示指定idx的页面
var myGallery = new UILite.Gallery();
myGallery.add(new UILite.File());
myGallery.add("<div>hello</div>");
myGallery.add(new UILite.Object("<div>world</div>"));
myGallery.setParent(document.body);
myGallery.show();
add()
继承与UILite.Container。
var myGallery = new UILite.Gallery({
mContent: [
new UILite.File(),
"<div>hello</div>",
new UILite.Object("<div>world</div>"),
],
mParent: document.body,
});
myGallery.show();
var idx = myGallery.getCurIdx();
myGallery.setCurIdx(2);
Jacob Pan ( jacobpan3g.github.io/cn )
Container({mContent: mParent: })
构造函数的参数与UILite.Object类一致,mContent可以是js数组对象
[
new UILite.File(),
<div>hello</div>
]
Container对象用于插入新dom的位置。
用于储存Container对象成员的数组
把当前对象设置成等待状态,会在dom加上uil_waiting
类,可通过css做相应的处理。
往maoContainees
添加内容,被保存前若不是UILite对象,会先创建成UILite.Object再保存。
这是一个虚类,一般不用于创建实例,而用于继承,如Window,Form,Gallery,Tab等都是继承Contianer类的。
Jacob Pan ( jacobpan3g.github.io/cn )
通过WebView,Mac App可以利用PC本地的Safari浏览器内核来加载html文件,里的js也可以和oc代码交互,通过这种方式可以直接适用前端技术来开发Mac App界面。
把前端文件以一整个文件夹拖进xcode项目,在弹出的对话框选择”Create folder references”,在”Add to targets”处勾选target,点击”Add”按钮,添加后,xcode左边的工程目录如下图,其中ui目录就是前端文件目录:
HelloWebView
├── HelloWebView
│ ├── HelloWebViewController.h
│ ├── HelloWebViewController.m
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Image.xcassets
│ ├── MainMenuxib
│ ├── ui
│ │ ├── css
│ │ ├── js
│ │ └── demo
│ │ └── index.html
│ └── Supporting Files
└── Products
通过这种方式添加进来的前端文件可以保持完整的层次结构,调用目录关系不会变。若通过”Create groups”来添加文件夹,所有文件其实都在项目根目录下,这样就会出现文件找不到的错误。
通过上述方式添加进来的前端文件,在最后打包App时会一起打包进去。
在相应的Controller.h添加WebView成员,并与NIB中WebView对像相连,还要添加头文件
...
#import <WebKit/WebKit.h>
@interface XXX: XXX {
...
}
@property (weak) IBOutlet WebView *webview;
在相应的Contriller.m中的awakeFromNib()
添加以下逻辑(ps: 没有该函数可以自行定义):
- (void)awakeFromNib
{
NSString* path = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html" inDirectory:@"ui/demo"];
NSURL* url = [NSURL fileURLWithPath:path];
NSURLRequest* request = [NSURLRequest requestWithURL:url] ;
[[self.webview mainFrame ] loadRequest:request];
}
注意:
ui/demo/index.html
在项目Target的”Build Phases” - “Link Binary With Libraries”中添加WebKit.framwork
然后编译运动,就能看到用前端代码事件的UI了,注意,若发现页面展示与预期效果不太一致,可以先在本机的safari上把html页面调通,再放在WebView上运行,因为WebView适用的就是safari的浏览器内核来加载html页面的。
Jacob Pan ( jacobpan3g.github.io/cn )