Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
Android Robolectric¼ÓÔØÔËÐб¾µØSo¶¯Ì¬¿â
 
×÷ÕߣºRocko À´Ô´£º51CTO ·¢²¼ÓÚ£º2016-12-12
  2243  次浏览      30
 

ǰÑÔ

Robolectric ÊÇ Android µÄµ¥Ôª²âÊÔ¿ò¼Ü£¬ÔËÐÐÎÞÐè Android Õæ»ú»·¾³Ö±½ÓÔËÐÐÔÚ JVM Ö®ÉÏ£¬ËùÒÔÔÚ test case ÔËÐÐËÙ¶ÈЧÂÊÉÏÓÐÁ˺ܴóÌáÉý£¬½Ó½üÓÚ Java JUnit test(JUnit test > Robolectric ? androidTest)¡£²»¹ý¿ò¼Ü±¾Éí²¢²»Ö§³Ö so ±¾µØ¿âµÄ¼ÓÔØÊ¹Ó㬼ÓÔØÊ±»áÖ±½Ó±¨´í£¬ÒòΪʵ¼ÊÉÏÔËÐл·¾³ÊǵçÄÔ»úÆ÷£¬¶øÎÒÃÇ´ò³öµÄ so ÎļþÊǸøÊÖ»úÉÏÓõÄËùÒÔµ±È»»á±¨´í¡£ËäÈ»ÔÚ GitHub ÉϺܶàÈËÎʹý¹ØÓÚʹÓà so µÄÎÊÌ⵫»ù±¾¶¼½¨Òé˵²»ÒªÔÚµ¥Ôª²âÊÔÖÐÈ¥¼ÓÔØ±¾µØ¿â£¬ÕâÔÚÔ­ÔòÉÏÊÇÒªÕâô×ö£¬µ«¿ÉÄÜÓÐЩÏîÄ¿ÖÐ×öÆðÀ´¾ÍÓÐЩÀ§ÄÑÁË£¬±ÈÈçÔÚ´úÂë½á¹¹²»¹»ºÃ¡¢ÒÀÀµñîºÏ½Ï´ó»òÕß±¾Éí¾Í¶Ô so ¿âÒÀÀµºÜ´óµÄÇé¿öÏ¡£ËùÒÔÏÂÃæËµËµÔÚÏîÄ¿ÖÐ Robolectric ÒªÔõô½â¾öÐèÒª¼ÓÔØÔËÐб¾µØ so ¿âÕâ¸öÎÊÌâ¡£

¶¯Ì¬¿â

¶¯Ì¬¿âÓֳƶ¯Ì¬Á´½Ó¿â(Dynamic-link library Ëõд DLL)£¬ÊÇÒ»¸ö°üº¬¿ÉÓɶà¸ö³ÌÐòͬʱʹÓõĴúÂëºÍÊý¾ÝµÄ¿â£¬DLL ²»ÊÇ¿ÉÖ´ÐÐÎļþ¡£¶¯Ì¬Á´½ÓÌṩÁËÒ»ÖÖ·½·¨£¬Ê¹½ø³Ì¿ÉÒÔµ÷Óò»ÊôÓÚÆä¿ÉÖ´ÐдúÂëµÄº¯Êý¡£º¯ÊýµÄ¿ÉÖ´ÐдúÂëλÓÚÒ»¸ö DLL ÖУ¬¸Ã DLL °üº¬Ò»¸ö»ò¶à¸öÒѱ»±àÒë¡¢Á´½Ó²¢ÓëʹÓÃËüÃǵĽø³Ì·Ö¿ª´æ´¢µÄº¯Êý¡£DLL »¹ÓÐÖúÓÚ¹²ÏíÊý¾ÝºÍ×ÊÔ´¡£¶à¸öÓ¦ÓóÌÐò¿Éͬʱ·ÃÎÊÄÚ´æÖе¥¸öDLL ¸±±¾µÄÄÚÈÝ¡£DLL ÊÇÒ»¸ö°üº¬¿ÉÓɶà¸ö³ÌÐòͬʱʹÓõĴúÂëºÍÊý¾ÝµÄ¿â¡£Windows϶¯Ì¬¿âΪ .dll ºó׺(Ò»°ãΪ PE ¸ñʽ)£¬ÔÚ Linux ÔÚΪ .so ºó׺(Ò»°ãΪ ELF ¸ñʽ)£¬macOSÏÂΪ .dylib ºó׺(Ò»°ãΪ Mach-O ¸ñʽ)¡£ÓÉÓÚ CPU ¼Ü¹¹ºÍ¶¯Ì¬¿âÎļþ¸ñʽµÄ²»Í¬Òò¶øÔÚ²»Í¬Æ½Ì¨Ï²»ÄÜͨÓá£ÆäËüϸ½ÚµÄ¶«Î÷¾Í²»Õ¹¿ªÁËÒòΪҲ²»»á :-)

¶ø Android ±¾ÉíÊÇ Linux ϵͳ£¬ËùÒÔÓõĶ¯Ì¬¿âÒ²ÊÇ .so µÄÎļþ£¬Òò¶øÔËÐÐÓë JVM µÄ Robolectric ÊDz»ÄÜÖ±½Ó¼ÓÔØÊ¹ÓõÄ(Linux ijЩÇé¿öÏ¿ÉÓã¬ÏÂÃæÌáµ½)¡£

Robolectric ÖÐʹÓö¯Ì¬¿â

ÎÒÃÇÖªµÀ¶¯Ì¬¿âÒ»°ã¶¼ÊÇ´ò¸øÌض¨Æ½Ì¨¡¢Ìض¨ CPU ¼Ü¹¹Óõģ¬ËùÒÔÒª½â¾öÔÚ Robolectric ϼÓÔØÔËÐÐ so ¶¯Ì¬¿âµÄÎÊÌâµÄ˼·¾ÍÊÇÔÚ²»Í¬ Robolectric ÔËÐÐÆ½Ì¨ÏÂÈ¥´¦Àí¼ÓÔØ²»Í¬µÄ¶¯Ì¬¿â£¬ËùÒÔÄãÒªÔÚ Ronbolectriv ÖÐʹÓÃµÄ so ¶¯Ì¬¿â×îºÃÒªÓÐÔ´Â벻ȻÔÚ macOS ºÍ Windows ϾͲ»¾ÍºÃ´¦ÀíÁË¡£

Note: ×¢Ò⶯̬¿âÃû³ÆÒÑ lib ¿ªÍ·¡£

Linux Ï Robolectric ÖÐʹÓö¯Ì¬¿â

Android Óë Linux Í¬ÆøÁ¬Ö¦£¬ËùÒԵײãµÄ¶«Î÷ºÜ¶àÊÇͨÓõ쬶¯Ì¬¿âÒ²Ò»Ñù¡£ÎÒÃÇ Android ʹÓà so ʱһ°ãÒ²Òª¶Ô²»Í¬ CPU ¼Ü¹¹µÄÊÖ»úÏÂʹÓò»Í¬µÄ so Îļþ£¬Æ©È磺armeabi-v7a¡¢mips¡¢x86¡£¶øÎÒÃÇʹÓÃµÄ LInux ·¢ÐаæÒ»°ã¶¼ÊÇ 64 λµÄ£¬ËùÒÔÔ­ÀíÉÏÎÒÃÇʹÓÃx86-64 µÄ¶¯Ì¬¿âÊÇ¿ÉÒԵ쬲»¹ý¿ÉÄÜÐèÒª´¦ÀíÒÀÀµ¿âÎÊÌâÈç¹ûÄãµÄ±¾µØ´úÂëÀïÓÐ include ÆäËüÒÀÀµµÄ»°¡£Èç¹ûû¼Ó½øÀ´ Robolectric ÔËÐоͻᱨÈçϵĴíÎó£º

java.lang.UnsatisfiedLinkError: xxx/xxx.so xxx ¶¯Ì¬¿âÕÒ²»µ½¡£ 

xxx.so ¾ÍÊÇÄãËùʹÓà so µÄÒÀÀµ£¬±ÈÈç°ÑÐÂÀË΢²© SDK µÄ x86-64 µÄ libweibosdkcore.so ¼ÓÔØ½øÀ´µÄ»°¾Í»á±¨ liblog.so µÈÕÒ²»µ½£¬ÒòΪ libweibosdkcore ÖÐÓÐ¶Ô Android liblog µÈ so ¿âµÄÒÀÀµ¡£ÄÇÕâ¸öÎÊÌâÔõô½â¾öÄØ¡£ÎÒÃÇÏëÏë´ò°ü so ¿âʱÓõÄÊÇ ndk£¬ÐèҪʹÓà ndk-bundle ¹¤¾ß£¬ÎÒÃÇÏëÏ룬¸ú±àÒë apk ²î²»¶à£¬apk ´ò°üÐèÒª sdk ¹¤¾ß£¬compileSdk Àï¾ÍÊÇÎÒÃDZàÒëµÄÒÀÀµ£¬ÀïÃæÓÐandroid.jar¡£ËùÒÔÎÒÃÇ¿ÉÒÔµ½ ndk-bundle ÀïÕÒÕÒ£¬×îºóÎÒÃÇ·¢ÏÖ²»Í¬ CPU ¼Ü¹¹Ï嵀 so ÒÀÀµ¿â¶¼ÊÇÓеģ¬ÏñÎÒÃÇÒ»°ãµÄµçÄÔ 64 λ CPU ¼´¿ÉʹÓà arch-x86_64 Ï嵀 so ¶¯Ì¬¿â£¬ËùÒÔÎÒÃÇÖ»ÐèÒªÔÚ¼ÓÔØÎÒÃdzÌÐòµÄ so ¿â֮ǰ¼ÓÔØÕâЩ±ØÐëµÄÒÀÀµ¼´¿É¡£´¦Àí´úÂëºóÃæÌù³ö¡£

×¢Òâ ndk-bundle ÀïµÄ so Ò²ÊÇÖ»ÄÜÔÚ Linux ÏÂÓõģ¬Èç¹ûÓÃÓÚÆäËüƽ̨»á±¨´í£¬Ô­ÒòÇ°ÃæÒÑ˵Ã÷¡£

    java.lang.UnsatisfiedLinkError: xxx.so: unknown file type, first eight bytes: 
0x7F 0x45 0x4C 0x46 0x02 0x01 0x01 0x00 

macOS Ï Robolectric ÖÐʹÓö¯Ì¬¿â

Ç°ÃæÒÑÌáµ½£¬²»Í¬Æ½Ì¨Ï¶¯Ì¬Á´½Ó¿âÊDz»Í¨Óõģ¬ËùÒÔ±ØÐë¶ÔÔ´ÂëÖØÐ±àÒë´ò°üÒÔÒÆÖ²µ½²»Í¬Æ½Ì¨Ï£¬Èç¹ûÄãµÄ so ûÓÐÔ´ÂëµÄ»°ÄÇÔÚ macOS ºÍ Windows ϾÍÐв»Í¨ÁË¡£ÖØÐ´ò°üÎÒÃÇ¿ÉÒÔ°´ÈçÏÂÁ½²½½øÐУº

    # ÏÈÉú³É .o £¬-I ºó¼Ó½ø Java jni µÄ±àÒëÒÀÀµ 

cc -c -I/System/Library/Frameworks/JavaVM.framework/Headers *.cpp

# ´ò°ü³É .dylib

g++ -dynamiclib -undefined suppress -flat_namespace *.o -o something.dylib

ijЩÒÀÀµ¿â¿ÉÒÔµ½ /usr/lib ÏÂÕÒÕÒ£¬±ÈÈç libc ºÍ libstdc++ ¡£

Windows Ï Robolectric ÖÐʹÓö¯Ì¬¿â

±¾ÈËûÓÐÔÚ Windows Ï¿ª·¢ËùÒÔÕⲿ·Ö¾ÍÂÔ¹ýÁË£¬Ë¼Â·ÊÇÒ»ÑùµÄ¡£

Sample

ÏÂÃæÊǼòµ¥µÄ´¦Àí´úÂëʾÀý¡£Ê×ÏÈн¨Ò»¸ö°üº¬ jni µÄ¹¤³Ì£¬ÀïÃæÐ´¸ö»ù±¾µÄ±¾µØ¿â£¬ÈçÏ£º

Õý³£Á÷³Ì

// native-lib.cpp 

#include <jni.h>
#include <string>

extern "C"
jstring
Java_xyz_rocko_rsnl_nativeinterface_NativeSample_stringFromJNI(
JNIEnv *env,
jobject /* this */) {

// ¼òµ¥·µ»Ø¸ö×Ö·û´®
std::string hello = "Hello from Native.";
return env->NewStringUTF(hello.c_str());
}

È»ºóÔÚ Application Æô¶¯Ê±»á¼ÓÔØÕâ¸ö±¾µØ¿â£º

    public class NativeLibsApplication extends Application { 

// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
}

´ËʱÔËÐÐ Robolectric µÄ test case ¾Í·¢ÉúÈçϱ¨´í£º

java.lang.UnsatisfiedLinkError: no native-lib in java.library.path  

´¦ÀíºóµÄÁ÷³Ì

Ê×ÏÈÁ÷³ÌÓ¦¸ÃÔÚÎÒÃǵĴúÂëÀï±ÜÃâ¿ÉÒÔÖ±½Ó¼ÓÔØ so ¶¯Ì¬¿â£¬È»ºó Robolectric ÔÚÆô¶¯Ê±×Ô¼ºÈ¥¼ÓÔØÐèÒªµÄ¶¯Ì¬¿â¡£

// NativeLibsApplication.java

    public class NativeLibsApplication extends Application { 

@Override public void onCreate() {
super.onCreate();
loadNativeLibraries();
}

/**
* ¼òµ¥ÈÃ×ÓÀà¿É×Ô¼ºÊµÏÖ
*/
protected void loadNativeLibraries() {

// ´úÂëÀïÕæÕý¼ÓÔØ±¾µØ¿âµÄµØ·½£¬µ±È»Äã×Ô¼ºµÄ¿ÉÒÔ´¦ÀíµØ¸ü½âñîÒ»µã¡£
NativeLibrariesManager.loadNativeLibraries();
}
}

È»ºóÎÒÃÇµÄ Robolectric Àï×Ô¶¨Òå×Ô¼ºµÄ Application£¬ÀïÃæ¸ù¾ÝÐèÒªÔÚ²»Í¬ÔËÐÐÆ½Ì¨ÏÂ×Ô¼º¼ÓÔØÐèÒªµÄ±¾µØ¶¯Ì¬¿â£¬Ê×Ïȸ´ÖÆÎÒÃǸø Robolectric Óõı¾µØ¿âµ½ test µÄ libs Îļþ¼ÐÀ°´²»Í¬Æ½Ì¨·ÖÀ࣬ÈçÏÂͼ£º

Linux ϵÄÎÒÃÇ´Ó ndk-bundle Àï¸´ÖÆÎÒÃÇÐèÒªµÄ .so£¬È»ºóÎÒÃÇ×Ô¼ºµÄ±¾µØ¿â´òÒ»¸ö x86-64 µÄ¼´¿É£¬×¢Òâ compileSdkVersion Ñ¡ÉϸßÒ»µãÖ§³Ö x86-64 µÄ°æ±¾¡£

È»ºóÖØÐÂÒÆÖ²´ò³ö macOS ÏµĶ¯Ì¬¿â£¬¼òµ¥Ð´¸ö´ò°ü½Å±¾ÈçÏ£º

// make_macOS_dylib.sh

#!/usr/bin/env bash 

OUTPUT=../../../build/intermediates/dylibs
mkdir -p ${OUTPUT}

# .o file
cc -c -I/System/Library/Frameworks/JavaVM.framework/Headers *.cpp -o ${OUTPUT}/libnative-lib.o

# .dylib file
g++ -dynamiclib -undefined suppress -flat_namespace ${OUTPUT}/*.o -o ${OUTPUT}/libnative-lib.dylib

libnative-lib.dylib ¾ÍÊÇÎÒÃÇÒªµÄ¡£

È»ºóÎÒÃÇ×Ô¶¨Òå Application ´¦Àí¼ÓÔØÕâЩ¶¯Ì¬¿â£º

// RobolectricApplication.java

    public class RobolectricApplication extends NativeLibsApplication { 

static {
ShadowLog.stream = System.out; //Android logcat output.
}

@Override protected void loadNativeLibraries() {
//Disable super class load so file.
//super.loadNativeLibraries();
Log.d(TAG, "=====>> Robolectric start native libraries.");

String libsBasePath =
new File(new File("").getAbsolutePath() + "/src/test/libs").getAbsolutePath();
String os = System.getProperty("os.name");
os = !TextUtils.isEmpty(os) ? os : "";
List<File> soFileList = new ArrayList<>();
String systemArchPath = libsBasePath + "/framework/";
//!!! 64 λ»úÆ÷Ï´¦Àí
if (os.contains("Mac")) {
//load system library if need
String macSysSoBasePath = systemArchPath + "macOS/";
soFileList.addAll(addLibs(macSysSoBasePath));
// App so...
String macAppSoPath = libsBasePath + "/macOS_x86-64/";
// macÏÂsoҪʹÓÃmacOSרÓÿâ
soFileList.addAll(addLibs(macAppSoPath));
} else if (os.contains("Linux")) {
//load system library if need
String linuxSysSoBasePath = systemArchPath + "arch_x86-64/";
soFileList.addAll(addLibs(linuxSysSoBasePath));
// App so...
String linuxAppSoPath = libsBasePath + "/linux_x86-64/";
soFileList.addAll(addLibs(linuxAppSoPath));
} else if (os.contains("Windows")) {
// ignore
}

for (File soFie : soFileList) {
System.load(soFie.getAbsolutePath());
}
}

private List<File> addLibs(@NonNull String path) {
File[] basePathFiles = new File(path).listFiles();
List<File> pathFilesList = new ArrayList<>();
if (basePathFiles != null && basePathFiles.length > 0) {
pathFilesList.addAll(Arrays.asList(basePathFiles));
}
return pathFilesList;
}
}

ÏÖÔھͿÉÒÔ¼ÓÔØÁË£¬ÔËÐÐÈçÏ test case£¬½á¹ûÈçÏÂͼ£¬³É¹¦ÁË¡£

    @Test public void testLoadNativeLibrariesSuccess() throws Exception { 
String nativeExcepted = "Hello from Native.";
String result = NativeSample.stringFromJNI();
Log.d(TAG, "result: " + result);
assertEquals(nativeExcepted, result);
}

 

End

Linux ÏÂʹÓÃ×î¿ìËÙ·½±ã£¬Ö»ÐèÒª´ò°ü³ÌÐòµÄ so ʱ˳±ã´ò°ü³ö x86-64 µÄ so £¬È»ºó¸´ÖÆ ndk-bundle µÄ so ¼ÓÉÏÐèÒªµÄÒÀÀµ¼´¿É¡£macOS ºÍ Windows ϾÍÐèÒª×Ô¼º´ò°ü³ö¸÷×ÔÆ½Ì¨ÏµĶ¯Ì¬¿â²Å¿ÉʹÓã¬Èç¹û´úÂëÀïÓÐ Android ×Ô´ø so ÒÀÀµµÄ»°ÄǾÍÐèÒª×Ô¼ºÈ¥ÖØÐÂÒÆÖ²±àÒë´ò°ü ndk-bundle ÀïµÄ¶¯Ì¬¿âÁË¡£

ÏîĿʵÀýÔ´Â룺RobolectricSupportNativeLibs

   
2243 ´Îä¯ÀÀ       30
 
Ïà¹ØÎÄÕÂ

ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
ÊÖ»ú¿Í»§¶ËUI²âÊÔ·ÖÎö
iPhoneÏûÏ¢ÍÆËÍ»úÖÆÊµÏÖÓë̽ÌÖ
AndroidÊÖ»ú¿ª·¢£¨Ò»£©
 
Ïà¹ØÎĵµ

Android_UI¹Ù·½Éè¼Æ½Ì³Ì
ÊÖ»ú¿ª·¢Æ½Ì¨½éÉÜ
androidÅÄÕÕ¼°ÉÏ´«¹¦ÄÜ
Android½²ÒåÖÇÄÜÊÖ»ú¿ª·¢
Ïà¹Ø¿Î³Ì

Android¸ß¼¶Òƶ¯Ó¦ÓóÌÐò
Androidϵͳ¿ª·¢
AndroidÓ¦Óÿª·¢
ÊÖ»úÈí¼þ²âÊÔ
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

androidÈË»ú½çÃæÖ¸ÄÏ
AndroidÊÖ»ú¿ª·¢£¨Ò»£©
AndroidÊÖ»ú¿ª·¢£¨¶þ£©
AndroidÊÖ»ú¿ª·¢£¨Èý£©
AndroidÊÖ»ú¿ª·¢£¨ËÄ£©
iPhoneÏûÏ¢ÍÆËÍ»úÖÆÊµÏÖ̽ÌÖ
ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
ÊÖ»ú¿Í»§¶ËUI²âÊÔ·ÖÎö
ÊÖ»úÈí¼þ×Ô¶¯»¯²âÊÔÑо¿±¨¸æ


Android¸ß¼¶Òƶ¯Ó¦ÓóÌÐò
AndroidÓ¦Óÿª·¢
Androidϵͳ¿ª·¢
ÊÖ»úÈí¼þ²âÊÔ
ǶÈëʽÈí¼þ²âÊÔ
AndroidÈí¡¢Ó²¡¢ÔÆÕûºÏ


ÁìÏÈIT¹«Ë¾ android¿ª·¢Æ½Ì¨×î¼Ñʵ¼ù
±±¾© Android¿ª·¢¼¼Êõ½ø½×
ijÐÂÄÜÔ´ÁìÓòÆóÒµ Android¿ª·¢¼¼Êõ
ijº½Ì칫˾ Android¡¢IOSÓ¦ÓÃÈí¼þ¿ª·¢
°¢¶û¿¨ÌØ LinuxÄÚºËÇý¶¯
°¬Ä¬Éú ǶÈëʽÈí¼þ¼Ü¹¹Éè¼Æ
Î÷ÃÅ×Ó Ç¶Èëʽ¼Ü¹¹Éè¼Æ