spaceandroid
1. app:和android:namespace的區別
在 Android Studio 上為第三方和自定義控制項寫命名空間就比較容易了,直接統一寫為 xmlns:app=」http://schemas.android.com/apk/res-auto」 即可,無需帶上麻煩的包名,當然,如果你在 Android Studio並且使用 Gradle 構建的時候,不這樣寫也無法通過編譯
2. android是什麼文件夾可以刪除
分析如下:
可以刪除,但是會重新生成的。這個是系統的緩存文件,刪了之後可能你存在手機上 的一些東西就不見了。建議不要刪除,裡面一個是data文件及是存放數據的一個obb文件夾。
(2)spaceandroid擴展閱讀
1、Android是一種基於linux的自由及開放源代碼的操作系統,主要使用於移動設備,如智能手機和平板電腦,由Google公司和開放手機聯盟領導及開發。尚未有統一中文名稱,中國大陸地區較多人使用「安卓」或「安致」。Android操作系統最初由Andy Rubin開發,主要支持手機。2005年8月由Google收購注資。2007年11月,Google與84家硬體製造商、軟體開發商及電信營運商組建開放手機聯盟共同研發改良Android系統。隨後Google以Apache開源許可證的授權方式,發布了Android的源代碼。第一部Android智能手機發布於2008年10月。
2、Android一詞的本義指「機器人」,同時也是Google於2007年11月5日宣布的基於Linux平台的開源手機操作系統的名稱,該平台由操作系統、中間件、用戶界面和應用軟體組成。Android的Logo是由Ascender公司設計的,誕生於2010年,其設計靈感源於男女廁所門上的圖形符號, 於是布洛克繪制了一個簡單的機器人,它的軀干就像錫罐的形狀,頭上還有兩根天線,Android小機器人便誕生了。其中的文字使用了Ascender公司專門製作的稱之為「Droid 」 的字體。Android是一個全身綠色的機器人,綠色也是Android的標志。
3、Android的系統架構和其操作系統一樣,採用了分層的架構。從架構圖看,Android分為四個層,從高層到低層分別是應用程序層、應用程序框架層、系統運行庫層和Linux內核層。
4、Android 是運行於Linux kernel之上,但並不是GNU/Linux。因為在一般GNU/Linux 里支持的功能,Android 大都沒有支持,包括Cairo、X11、Alsa、FFmpeg、GTK、Pango及Glibc等都被移除掉了。Android又以Bionic 取代Glibc、以Skia 取代Cairo、再以opencore取代FFmpeg等等。Android 為了達到商業應用,必須移除被GNU GPL授權證所約束的部份,例如Android將驅動程序移到 Userspace,使得Linux driver 與 Linux kernel徹底分開。Bionic/Libc/Kernel/ 並非標準的Kernel header files。Android 的 Kernel header 是利用工具由 Linux Kernel header 所產生的,這樣做是為了保留常數、數據結構與宏。
5、Android開發四大組件分別是:活動(Activity): 用於表現功能。服務(Service): 後台運行服務,不提供界面呈現。廣播接收器(BroadcastReceiver):用於接收廣播。內容提供商(Content Provider): 支持在多個應用中存儲和讀取數據,相當於資料庫。
參考資料:(網路:Android)
3. android (安卓)是完全開源的嗎
android (安卓)是完全開源的。
Android是一種基於Linux的自由及開放源代碼的操作系統。主要使用於移動設備,如智能手機和平板電腦,由Google(谷歌)公司和開放手機聯盟領導及開發。
尚未有統一中文名稱,中國大陸地區較多人使用「安卓」或「安致」。Android操作系統最初由Andy Rubin開發,主要支持手機。2005年8月由Google收購注資。
2007年11月,Google與84家硬體製造商、軟體開發商及電信營運商組建開放手機聯盟共同研發改良Android系統。隨後Google以Apache開源許可證的授權方式,發布了Android的源代碼。
(3)spaceandroid擴展閱讀:
一、發展歷程
2003年10月,Andy Rubin等人創建Android公司,並組建Android團隊。
2005年8月17日,Google低調收購了成立僅22個月的高科技企業Android及其團隊。安迪魯賓成為Google公司工程部副總裁,繼續負責Android項目。
2007年11月5日,谷歌公司正式向外界展示了這款名為Android的操作系統,並且在這天谷歌宣布建立一個全球性的聯盟組織,該組織由34家手機製造商、軟體開發商、電信運營商以及晶元製造商共同組成。
並與84家硬體製造商、軟體開發商及電信營運商組成開放手持設備聯盟(Open Handset Alliance)來共同研發改良Android系統,這一聯盟將支持谷歌發布的手機操作系統以及應用軟體,Google以Apache免費開源許可證的授權方式,發布了Android的源代碼。
2008年,在GoogleI/O大會上,谷歌提出了AndroidHAL架構圖,在同年8月18號,Android獲得了美國聯邦通信委員會(FCC)的批准,在2008年9月,谷歌正式發布了Android 1.0系統,這也是Android系統最早的版本。
二、系統內核
Android 是運行於Linux kernel之上,但並不是GNU/Linux。因為在一般GNU/Linux 里支持的功能,Android 大都沒有支持,包括Cairo、X11、Alsa、FFmpeg、GTK、Pango及Glibc等都被移除掉了。
Android又以Bionic 取代Glibc、以Skia 取代Cairo、再以opencore取代FFmpeg等等。Android 為了達到商業應用,必須移除被GNU GPL授權證所約束的部份,例如Android將驅動程序移到 Userspace,使得Linux driver 與 Linux kernel徹底分開。
Bionic/Libc/Kernel/ 並非標準的Kernel header files。Android 的 Kernel header 是利用工具由 Linux Kernel header 所產生的,這樣做是為了保留常數、數據結構與宏。
Android 的 Linux kernel控制包括安全(Security),存儲器管理(Memory Management),程序管理(Process Management),網路堆棧(Network Stack),驅動程序模型(Driver Model)等。下載Android源碼之前,先要安裝其構建工具 Repo來初始化源碼。Repo 是 Android 用來輔助Git工作的一個工具。
4. 如何在android的jni線程中實現回調
JNI回調是指在c/c++代碼中調用java函數,當在c/c++的線程中執行回調函數時,會導致回調失敗。
其中一種在Android系統的解決方案是:
把c/c++中所有線程的創建,由pthread_create函數替換為由Java層的創建線程的函數AndroidRuntime::createJavaThread。
假設有c++函數:
[cpp] view plain
void *thread_entry(void *args)
{
while(1)
{
printf("thread running...\n");
sleep(1);
}
}
void init()
{
pthread_t thread;
pthread_create(&thread,NULL,thread_entry,(void *)NULL);
}
init()函數創建一個線程,需要在該線程中調用java類Test的回調函數Receive:
[cpp] view plain
public void Receive(char buffer[],int length){
String msg = new String(buffer);
msg = "received from jni callback:" + msg;
Log.d("Test", msg);
}
首先在c++中定義回調函數指針:
[cpp] view plain
//test.h
#include <pthread.h>
//function type for receiving data from native
typedef void (*ReceiveCallback)(unsigned char *buf, int len);
/** Callback for creating a thread that can call into the Java framework code.
* This must be used to create any threads that report events up to the framework.
*/
typedef pthread_t (* CreateThreadCallback)(const char* name, void (*start)(void *), void* arg);
typedef struct{
ReceiveCallback recv_cb;
CreateThreadCallback create_thread_cb;
}Callback;
再修改c++中的init和thread_entry函數:
[cpp] view plain
//test.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/wait.h>
#include <unistd.h>
#include "test.h"
void *thread_entry(void *args)
{
char *str = "i'm happy now";
Callback cb = NULL;
int len;
if(args != NULL){
cb = (Callback *)args;
}
len = strlen(str);
while(1)
{
printf("thread running...\n");
//invoke callback method to java
if(cb != NULL && cb->recv_cb != NULL){
cb->recv_cb((unsigned char*)str, len);
}
sleep(1);
}
}
void init(Callback *cb)
{
pthread_t thread;
//pthread_create(&thread,NULL,thread_entry,(void *)NULL);
if(cb != NULL && cb->create_thread_cb != NULL)
{
cb->create_thread_cb("thread",thread_entry,(void *)cb);
}
}
然後在jni中實現回調函數,以及其他實現:
[cpp] view plain
//jni_test.c
#include <stdlib.h>
#include <malloc.h>
#include <jni.h>
#include <JNIHelp.h>
#include "android_runtime/AndroidRuntime.h"
#include "test.h"
#define RADIO_PROVIDER_CLASS_NAME "com/tonny/Test"
using namespace android;
static jobject mCallbacksObj = NULL;
static jmethodID method_receive;
static void (JNIEnv* env, const char* methodName) {
if (env->ExceptionCheck()) {
LOGE("An exception was thrown by callback '%s'.", methodName);
LOGE_EX(env);
env->ExceptionClear();
}
}
static void receive_callback(unsigned char *buf, int len)
{
int i;
JNIEnv* env = AndroidRuntime::getJNIEnv();
jcharArray array = env->NewCharArray(len);
jchar *pArray ;
if(array == NULL){
LOGE("receive_callback: NewCharArray error.");
return;
}
pArray = (jchar*)calloc(len, sizeof(jchar));
if(pArray == NULL){
LOGE("receive_callback: calloc error.");
return;
}
// buffer to jchar array
for(i = 0; i < len; i++)
{
*(pArray + i) = *(buf + i);
}
// buffer to jcharArray
env->SetCharArrayRegion(array,0,len,pArray);
//invoke java callback method
env->CallVoidMethod(mCallbacksObj, method_receive,array,len);
//release resource
env->DeleteLocalRef(array);
free(pArray);
pArray = NULL;
(env, __FUNCTION__);
}
static pthread_t create_thread_callback(const char* name, void (*start)(void *), void* arg)
{
return (pthread_t)AndroidRuntime::createJavaThread(name, start, arg);
}
static Callback mCallbacks = {
receive_callback,
create_thread_callback
};
static void jni_class_init_native
(JNIEnv* env, jclass clazz)
{
method_receive = env->GetMethodID(clazz, "Receive", "([CI)V");
}
static int jni_init
(JNIEnv *env, jobject obj)
{
if (!mCallbacksObj)
mCallbacksObj = env->NewGlobalRef(obj);
return init(&mCallbacks);
}
static const JNINativeMethod gMethods[] = {
{ "class_init_native", "()V", (void *)jni_class_init_native },
{ "native_init", "()I", (void *)jni_init },
};
static int registerMethods(JNIEnv* env) {
const char* const kClassName = RADIO_PROVIDER_CLASS_NAME;
jclass clazz;
/* look up the class */
clazz = env->FindClass(kClassName);
if (clazz == NULL) {
LOGE("Can't find class %s/n", kClassName);
return -1;
}
/* register all the methods */
if (env->RegisterNatives(clazz,gMethods,sizeof(gMethods)/sizeof(gMethods[0])) != JNI_OK)
{
LOGE("Failed registering methods for %s/n", kClassName);
return -1;
}
/* fill out the rest of the ID cache */
return 0;
}
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env = NULL;
jint result = -1;
LOGI("Radio JNI_OnLoad");
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
LOGE("ERROR: GetEnv failed/n");
goto fail;
}
if(env == NULL){
goto fail;
}
if (registerMethods(env) != 0) {
LOGE("ERROR: PlatformLibrary native registration failed/n");
goto fail;
}
/* success -- return valid version number */
result = JNI_VERSION_1_4;
fail:
return result;
}
jni的Android.mk文件中共享庫設置為:
[cpp] view plain
LOCAL_SHARED_LIBRARIES := liblog libcutils libandroid_runtime libnativehelper
最後再實現Java中的Test類:
[java] view plain
//com.tonny.Test.java
public class Test {
static{
try {
System.loadLibrary("test");
class_init_native();
} catch(UnsatisfiedLinkError ule){
System.err.println("WARNING: Could not load library libtest.so!");
}
}
public int initialize() {
return native_radio_init();
}
public void Receive(char buffer[],int length){
String msg = new String(buffer);
msg = "received from jni callback" + msg;
Log.d("Test", msg);
}
protected static native void class_init_native();
protected native int native_init();
}
5. 如何在Android下使用Binder
1概述
Binder是基於OpenBinder,在Android系統上使用的進程間通信機制。
Binder基於Client-Server通信模式,本質上可以理解為它實現了Client對Server對象的遠程調用。比如,有某個binder對象A位於Server中,該對象提供了一套函數用以實現對服務的請求,而在一個或多個Client中包含對象A的引用,Client通過該引用可以調用遠端Server中對象A的介面函數,這種遠端調用對Client而言,與調用本地對象並無區別。
2 通信模型
Binder機制定義了四個組件,分別是Client,Server,ServiceManager和binder驅動,其中Client,Server,ServiceManager運行於用戶空間,binder驅動運行於內核空間。
binder驅動
binder驅動是內核中的一個字元設備驅動/dev/binder,它是整個Binder通信機制的核心。Client,Server,ServiceManager通過open()和ioctl()文件操作函數與binder驅動進行通信,從而實現了Client向Server發送請求,Server處理請求並返回結果到Client。具體來說,它負責進程之間Binder通信的建立,Binder在進程之間的傳遞,Binder引用計數管理,數據包在進程之間的傳遞和交互等一系列底層支持。
ServiceManager
ServiceManager是一個守護進程,負責管理服務,即所有的Server需要向ServiceManager注冊服務。同時,ServiceManager向Client提供查詢和獲取Server的介面。
3 binder通信實例
實現一個binder通信實例,需要經過以下步驟:
(1)獲得ServiceManager的對象引用
(2)向ServiceManager注冊新的Service
(3)在Client中通過ServiceManager獲得Service對象引用
(3)在Client中發送請求,由Service返回結果。
下面看具體的代碼如何實現。
3.1 libmyservice代碼實現
(1)新建目錄frameworks/base/myservice/libservice,進入該目錄
view plain
$ cd frameworks/base
$ mkdir myservice
$ cd myservice
$ mkdir libmyservice
$ cd libmyservice
(2)編寫libmyservice/myservic.h文件
view plain
#include <utils/threads.h>
#include <utils/RefBase.h>
#include <binder/IInterface.h>
#include <binder/BpBinder.h>
#include <binder/Parcel.h>
namespace android {
class MyService : public BBinder
{
mutable Mutex mLock;
int32_t mNextConnId;
public:
static int instantiate();
MyService();
virtual ~MyService();
virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t);
};
}; //namespace
(2)編寫libservice/myservice.cpp文件
view plain
#include "myservice.h"
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
namespace android {
static struct sigaction oldact;
static pthread_key_t sigbuskey;
int MyService::instantiate()
{
LOGE("MyService instantiate");
// defaultServiceManager ()獲得ServiceManager的對象引用,addService()可向ServiceManager注冊新的服務
int r = defaultServiceManager()->addService(String16("android.myservice"), new MyService());
LOGE("MyService r = %d/n", r);
return r;
}
MyService::MyService()
{
LOGV("MyService created");
mNextConnId = 1;
pthread_key_create(&sigbuskey, NULL);
}
MyService::~MyService()
{
pthread_key_delete(sigbuskey);
LOGV("MyService destroyed");
}
// 每個系統服務都繼承自BBinder類,都應重寫BBinder的onTransact虛函數。當用戶發送請求到達Service時,系統框架會調用Service的onTransact函數,該函數分析接收到的數據包,調用相應的介面函數處理請求
status_t MyService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code)
{
case 0: {
pid_t pid = data.readInt32();
int num = data.readInt32();
num = num + 100;
reply->writeInt32(num);
return NO_ERROR;
}
break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
}; //namespace
(3)編寫libservice/Android.mk文件
view plain
# File: Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := myservice.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
LOCAL_SHARED_LIBRARIES := libutils libbinder
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := libmyservice
include $(BUILD_SHARED_LIBRARY)
(4)編譯libmyservice.so動態庫
在android源碼主目錄下
view plain
$ source build/envsetup.sh
including device/htc/passion/vendorsetup.sh
including device/samsung/crespo4g/vendorsetup.sh
including device/samsung/crespo/vendorsetup.sh
$ mmm frameworks/base/myservice/libmyservice/
編譯成功後生成文件:out/target/proct/generic/system/lib/libmyservice.so
3.2 myserver代碼實現
(1)新建目錄myservice/myserver,並進入該目錄
(2)編寫myserver/myserver.cpp文件
view plain
#include <sys/types.h>
#include <unistd.h>
#include <grp.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
#include <private/android_filesystem_config.h>
#include "../libmyservice/myservice.h"
using namespace android;
int main(int argc, char** argv)
{
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();//獲得ServiceManager介面
LOGI("ServiceManager: %p", sm.get());
MyService::instantiate();
//執行addService()函數,注冊服務
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
//進入循環,等待客戶端的請求
return 0;
}
(3)編寫myserver/Android.mk文件
view plain
# File: Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
myserver.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
LOCAL_SHARED_LIBRARIES := \
libutils libbinder libmyservice
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := myserver
include $(BUILD_EXECUTABLE)
(4)編譯myserver可執行程序
在android源碼主目錄下執行:
view plain
$mmm frameworks/base/myservice/myserver/
編譯成功後生成文件:out/target/proct/generic/symbols/system/bin/myserver
3.3 MyClient客戶端代碼實現
(1)新建目錄myservice/myclient,進入該目錄
(2)編寫myclient/myclient.h文件
view plain
namespace android
{
class MyClient {
public:
void add100(int n);
private:
static const void getMyService();
//通過ServiceManager獲取服務介面
};
}; //namespace
(3)編寫myclient/myclient.cpp文件
view plain
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include "myclient.h"
namespace android
{
sp<IBinder> binder;
void MyClient::add100(int n)
{
getMyService();
Parcel data, reply;
int answer;
data.writeInt32(getpid());
data.writeInt32(n);
LOGE("BpMyService::create remote()->transact()/n");
binder->transact(0, data, &reply);
answer = reply.readInt32();
printf("answner=%d/n", answer);
return;
}
const void MyClient::getMyService()
{
sp<IServiceManager> sm = defaultServiceManager();
binder = sm->getService(String16("android.myservice"));
LOGE("MyClient::getMyService %p/n",sm.get());
if (binder == 0) {
LOGW("MyService not published, waiting...");
return;
}
}
}; //namespace
using namespace android;
int main(int argc, char** argv)
{
MyClient* p = new MyClient();
p->add100(1);
return 0;
}
(4)編寫myclient/Android.mk文件
view plain
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
myclient.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
LOCAL_SHARED_LIBRARIES := \
libutils libbinder libmyservice
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := myclient
include $(BUILD_EXECUTABLE)
(5)編譯myclient可執行程序
在android源碼主目錄下,執行:
view plain
$ mmm frameworks/base/myservice/myclient/
編譯成功後生成可執行文件:out/target/proct/generic/symbols/system/bin/myclient
3.4在模擬器上運行
(1)啟動模擬器
view plain
$ cd ~/software/android/android-sdk-linux/tools
$ ./emulator -avd gbread -partition-size 512
(2)拷貝libmyservice.so到模擬器的/system/lib目錄
view plain
$cd out/target/proct/generic/obj/lib
$adb remount
$ adb push libmyservice.so /system/lib
159 KB/s (10084 bytes in 0.061s)
(3)拷貝myserver到模擬器的/system/bin目錄
view plain
$cd out/target/proct/generic/symbols/system/bin
$ adb push myserver /system/bin
668 KB/s (27508 bytes in 0.040s)
(4)拷貝myclient到/system/bin目錄
view plain
$ adb push myclient /system/bin
1549 KB/s (46840 bytes in 0.029s)
(5)在模擬器上啟動服務,並執行客戶端程序。
view plain
# adb shell
# cd system/bin
# ls my*
myclient
myserver
# ./myserver
# ./myclient
answner=101/n#
由客戶端程序的執行結果可知,由服務端返回的執行結果是正確的。