由於Ubuntu手機平台安全的限制,在Ubuntu手機的應用中我們只能訪問自己的空間.如果我們所需要訪問的文件不存在於我們應用所在的空間,我們是沒有辦法訪問到的.我們的應用只能訪問系統提供的庫.如果系統沒有所需要的庫的話,我們通過可以通過如下的方法實現:
我們可以選擇Ubuntu SDK所提供的標准的帶有C++ plugin的模版來實現.對於第二種情況,我們同樣需要在我們的項目中加入所需要的文件,並打包到我們的應用中去.第二種方法對於一些不存在於Ubuntu SDK所提供的標准庫裡的情況是非常有用的.比如我們可以得到PDF reader的庫的源碼,並編譯成為我們自己的庫.最終我們可以把這些庫一起打包並安裝到我們的手機中使用.
$ git clone' target='_blank'>https://github.com/liu-xiao-guo/studentlib_shared[/code]
我們的這個庫非常地簡單:
Student.h
#include<string>
class Student{
private:
std::string name;
public:
Student(std::string);
virtual void display();
};
student.cpp
#include <iostream>
#include "Student.h"
using namespace std;
Student::Student(string name):name(name){}
void Student::display(){
cout << "A student with name " << this->name << endl;
}
接下來,我們以armhf chroot為例,當然我們也可以對i386使用同樣的方法.我們通過我們已經安裝好的armhf chroot來編譯我們的這個庫.首先我們通過如下的方式進入到我的chroot:
$ click chroot -aarmhf -fubuntu-sdk-15.04 run
當我們進入到我買的chroot中後,我們就可以開始編譯我們的應用庫了.我們進入到我們的項目的根目錄中,並打入如下的命令
$ mkdir build
$ cd build
$ cmake ..
$ make
這樣在我們的build子目錄下就可以看到我們希望的庫了.
(click-ubuntu-sdk-15.04-armhf)liuxg@liuxg:~/qml/studentlib_shared/build$ ls
CMakeCache.txt CMakeFiles Makefile cmake_install.cmake libtestStudent.so
(click-ubuntu-sdk-15.04-armhf)liuxg@liuxg:~/qml/studentlib_shared/build$
2)創建一個帶有plugin的最基本的應用.
我們選擇"QML App with C++ plugin (qmake)"模版來創建一個最基本的testplugin應用.在這個應用中,我們將展示如何使用我們上面已經創建好的shared庫.
接下來,我們修改我們的mytype.cpp及mytype.h文件:
mytype.h
#ifndef MYTYPE_H
#define MYTYPE_H
#include <QObject>
class MyType : public QObject
{
Q_OBJECT
Q_PROPERTY( QString helloWorld READ helloWorld WRITE setHelloWorld NOTIFY helloWorldChanged )
public:
explicit MyType(QObject *parent = 0);
Q_INVOKABLE void testlib();
~MyType();
Q_SIGNALS:
void helloWorldChanged();
protected:
QString helloWorld() { return m_message; }
void setHelloWorld(QString msg) { m_message = msg; Q_EMIT helloWorldChanged(); }
QString m_message;
};
#endif // MYTYPE_H
mytype.cpp
#include "mytype.h"
#include "Student.h"
MyType::MyType(QObject *parent) :
QObject(parent),
m_message("")
{
}
void MyType::testlib()
{
Student student("johnddfsfdfdfds");
student.display();
}
MyType::~MyType() {
}
在上面的代碼中,我們已經使用了我們shared庫中的display()方法.如果這個時候我們去運行我們的應用的話,我們會發現我們的應用肯定是有錯誤的.這是因為它根本找不到它所需要的庫.在下面我們來嘗試把我們的庫打包到我們的項目中來.
我們首先在我們的項目中創建一個叫做libs的目錄,並把我們的shared庫考入到這個目錄中.這樣整個的項目的目錄就像:
liuxg@liuxg:~/qml/testplugin$ tree -L 3
.
├── backend
│ ├── Testplugin
│ │ ├── backend.cpp
│ │ ├── backend.h
│ │ ├── mytype.cpp
│ │ ├── mytype.h
│ │ ├── qmldir
│ │ └── Testplugin.pro
│ └── tests
│ └── unit
├── libs
│ ├── libs.pro
│ ├── libtestStudent.so
│ └── Student.h
├── manifest.json.in
├── po
│ └── testplugin.liu-xiao-guo.pot
├── testplugin
│ ├── Main.qml
│ ├── testplugin.apparmor
│ ├── testplugin.desktop
│ ├── testplugin.png
│ ├── testplugin.pro
│ └── tests
│ ├── autopilot
│ └── unit
├── testplugin.pro
└── testplugin.pro.user
在上面的顯示中,我們可以看到在libs目錄中除了一個我們看到的那個libtestStudent.so及header文件外,還有一個叫做libs.pro的文件.它的內容如下:
libs.pro
TEMPLATE = lib
load(ubuntu-click)
filetypes = qml png svg js qmltheme jpg qmlproject desktop wav so
OTHER_FILES = filetypes
for(filetype, filetypes) {
OTHER_FILES += *.$$filetype
}
other_files.path = $${UBUNTU_CLICK_PLUGIN_PATH}
other_files.files = $$OTHER_FILES
INSTALLS += other_files
message(The project1 will be installed in $${UBUNTU_CLICK_PLUGIN_PATH})
在上面的文件中,我們可以通過上面的方法把我們需要的.so文件拷入到我們所需要的目錄中.
最後在我們的"testplugin.pro"文件中需要加入我們的目錄"libs".
SUBDIRS += testplugin \
backend/Testplugin \
libs
在我們的"TestPlugin.pro"中,我們需要加入如下的句子:
LIBS += -L$$PWD/../../libs/ -ltestStudent
INCLUDEPATH += $$PWD/../../libs
DEPENDPATH += $$PWD/../../libs
在我們的QML文件中,我們是這樣來調用的:
Main.qml
...
Button {
anchors.centerIn: parent
text: "Test lib"
onClicked: {
myType.testlib();
}
}
...
最終,我們來編譯並部署我們的應用到我們的手機上:
我們可以查看在我們手機中的安裝文件.在我們的desktop中打入如下的命令:
$ adb shell
通過上面的命令進入到手機中,並進入到如下的目錄:
/opt/click.ubuntu.com/testplugin.liu-xiao-guo/current/lib/arm-linux-gnueabihf/
我們可以看到我們所需要的文件已經被成功安裝到該目錄中:
當我們點擊在應用中的按鈕"Test lib"時,我們可以在我們的SDK IDE中看見輸出:
上面輸出的字符串就是我們利用我們的庫來輸出的:
Student student("johnddfsfdfdfds");
student.display();
整個項目的源碼在https://github.com/liu-xiao-guo/testplugin