System Server是Android系统的核心,他在Dalvik虚拟机启动后立即开始初始化和运行。其它的系统服务在System Server进程的环境中运行。/base/services/java/com/android/server/SystemServer.java

Java代码 收藏代码
  1. /**
  2. *ThismethodiscalledfromZygotetoinitializethesystem.Thiswillcausethenative
  3. *services(SurfaceFlinger,AudioFlinger,etc..)tobestarted.Afterthatitwillcallback
  4. *upintoinit2()tostarttheAndroidservices.
  5. */
  6. native public static void init1(String[]args);
  7. public static void main(String[]args){
  8. if (System.currentTimeMillis()<EARLIEST_SUPPORTED_TIME){
  9. //Ifadevice'sclockisbefore1970(before0),alotof
  10. //APIscrashdealingwithnegativenumbers,notably
  11. //java.io.File#setLastModified,soinsteadwefakeitand
  12. //hopethattimefromcelltowersorNTPfixesit
  13. //shortly.
  14. Slog.w(TAG,"Systemclockisbefore1970;settingto1970." );
  15. SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
  16. }
  17. if (SamplingProfilerIntegration.isEnabled()){
  18. SamplingProfilerIntegration.start();
  19. timer=new Timer();
  20. timer.schedule(new TimerTask(){
  21. @Override
  22. public void run(){
  23. SamplingProfilerIntegration.writeSnapshot("system_server" );
  24. }
  25. },SNAPSHOT_INTERVAL,SNAPSHOT_INTERVAL);
  26. }
  27. //Thesystemserverhastorunallofthetime,soitneedstobe
  28. //asefficientaspossiblewithitsmemoryusage.
  29. VMRuntime.getRuntime().setTargetHeapUtilization(0 .8f);
  30. System.loadLibrary("android_servers" );
  31. init1(args);
  32. }
  33. public static final void init2(){
  34. Slog.i(TAG,"EnteredtheAndroidsystemserver!" );
  35. Threadthr=new ServerThread();
  36. thr.setName("android.server.ServerThread" );
  37. thr.start();
  38. }

在main函数中,首先检查系统时间设置和SamplingProfiler。然后加载一个叫android_servers的本地库,他提供本 地方法的接口(源程序在framework/base/services/jni/目录中)。然后调用本地方法设置服务。具体执行设置的代码在 frameworks/base/cmds/system_server/library/system_init.cpp中。

C代码 收藏代码
  1. extern "C" status_tsystem_init()
  2. {
  3. LOGI("Enteredsystem_init()" );
  4. sp<ProcessState>proc(ProcessState::self());
  5. sp<IServiceManager>sm=defaultServiceManager();
  6. LOGI("ServiceManager:%p\n" ,sm.get());
  7. sp<GrimReaper>grim=new GrimReaper();
  8. sm->asBinder()->linkToDeath(grim,grim.get(),0);
  9. char propBuf[PROPERTY_VALUE_MAX];
  10. property_get("system_init.startsurfaceflinger" ,propBuf, "1" );
  11. if (strcmp(propBuf, "1" )==0){
  12. //StarttheSurfaceFlinger
  13. SurfaceFlinger::instantiate();
  14. }
  15. //Startthesensorservice
  16. SensorService::instantiate();
  17. //Onthesimulator,audioflingeretaldon'tgetstartedthe
  18. //samewayasonthedevice,andweneedtostartthemhere
  19. if (!proc->supportsProcesses()){
  20. //StarttheAudioFlinger
  21. AudioFlinger::instantiate();
  22. //Startthemediaplaybackservice
  23. MediaPlayerService::instantiate();
  24. //Startthecameraservice
  25. CameraService::instantiate();
  26. //Starttheaudiopolicyservice
  27. AudioPolicyService::instantiate();
  28. }
  29. //AndnowstarttheAndroidruntime.Wehavetodothisbit
  30. //ofnastinessbecausetheAndroidruntimeinitializationrequires
  31. //someofthecoresystemservicestoalreadybestarted.
  32. //AllotherserversshouldjuststarttheAndroidruntimeat
  33. //thebeginningoftheirprocesses'smain(),beforecalling
  34. //theinitfunction.
  35. LOGI("Systemserver:startingAndroidruntime.\n" );
  36. AndroidRuntime*runtime=AndroidRuntime::getRuntime();
  37. LOGI("Systemserver:startingAndroidservices.\n" );
  38. runtime->callStatic("com/android/server/SystemServer" , "init2" );
  39. //Ifrunninginourownprocess,justgointothethread
  40. //pool.Otherwise,calltheinitializationfinished
  41. //functoletthisprocesscontinueitsinitilization.
  42. if (proc->supportsProcesses()){
  43. LOGI("Systemserver:enteringthreadpool.\n" );
  44. ProcessState::self()->startThreadPool();
  45. IPCThreadState::self()->joinThreadPool();
  46. LOGI("Systemserver:exitingthreadpool.\n" );
  47. }
  48. return NO_ERROR;
  49. }

等初始化传感器,视频,音频等服务后,调用一个回调方法init2 (在SystemServer.java中)。在上面的代码可以看到,这个方法开启了ServerThread来初始化其它的服务。

Java代码 收藏代码
  1. public void run(){
  2. EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
  3. SystemClock.uptimeMillis());
  4. Looper.prepare();
  5. android.os.Process.setThreadPriority(
  6. android.os.Process.THREAD_PRIORITY_FOREGROUND);
  7. BinderInternal.disableBackgroundScheduling(true );
  8. android.os.Process.setCanSelfBackground(false );
  9. //Checkwhetherwefailedtoshutdownlasttimewetried.
  10. {
  11. final StringshutdownAction=SystemProperties.get(
  12. ShutdownThread.SHUTDOWN_ACTION_PROPERTY,"" );
  13. if (shutdownAction!= null &&shutdownAction.length()> 0 ){
  14. boolean reboot=(shutdownAction.charAt( 0 )== '1' );
  15. final Stringreason;
  16. if (shutdownAction.length()> 1 ){
  17. reason=shutdownAction.substring(1 ,shutdownAction.length());
  18. }else {
  19. reason=null ;
  20. }
  21. ShutdownThread.rebootOrShutdown(reboot,reason);
  22. }
  23. }
  24. StringfactoryTestStr=SystemProperties.get("ro.factorytest" );
  25. int factoryTest= "" .equals(factoryTestStr)?SystemServer.FACTORY_TEST_OFF
  26. :Integer.parseInt(factoryTestStr);
  27. LightsServicelights=null ;
  28. PowerManagerServicepower=null ;
  29. BatteryServicebattery=null ;
  30. ConnectivityServiceconnectivity=null ;
  31. IPackageManagerpm=null ;
  32. Contextcontext=null ;
  33. WindowManagerServicewm=null ;
  34. BluetoothServicebluetooth=null ;
  35. BluetoothA2dpServicebluetoothA2dp=null ;
  36. HeadsetObserverheadset=null ;
  37. DockObserverdock=null ;
  38. UsbServiceusb=null ;
  39. UiModeManagerServiceuiMode=null ;
  40. RecognitionManagerServicerecognition=null ;
  41. ThrottleServicethrottle=null ;
  42. //Criticalservices...
  43. try {
  44. Slog.i(TAG,"EntropyService" );
  45. ServiceManager.addService("entropy" , new EntropyService());
  46. Slog.i(TAG,"PowerManager" );
  47. power=new PowerManagerService();
  48. ServiceManager.addService(Context.POWER_SERVICE,power);
  49. Slog.i(TAG,"ActivityManager" );
  50. context=ActivityManagerService.main(factoryTest);
  51. Slog.i(TAG,"TelephonyRegistry" );
  52. ServiceManager.addService("telephony.registry" , new TelephonyRegistry(context));
  53. AttributeCache.init(context);
  54. Slog.i(TAG,"PackageManager" );
  55. pm=PackageManagerService.main(context,
  56. factoryTest!=SystemServer.FACTORY_TEST_OFF);
  57. ActivityManagerService.setSystemProcess();
  58. mContentResolver=context.getContentResolver();
  59. //TheAccountManagermustcomebeforetheContentService
  60. try {
  61. Slog.i(TAG,"AccountManager" );
  62. ServiceManager.addService(Context.ACCOUNT_SERVICE,
  63. new AccountManagerService(context));
  64. }catch (Throwablee){
  65. Slog.e(TAG,"FailurestartingAccountManager" ,e);
  66. }
  67. Slog.i(TAG,"ContentManager" );
  68. ContentService.main(context,
  69. factoryTest==SystemServer.FACTORY_TEST_LOW_LEVEL);
  70. Slog.i(TAG,"SystemContentProviders" );
  71. ActivityManagerService.installSystemProviders();
  72. Slog.i(TAG,"BatteryService" );
  73. battery=new BatteryService(context);
  74. ServiceManager.addService("battery" ,battery);
  75. Slog.i(TAG,"LightsService" );
  76. lights=new LightsService(context);
  77. Slog.i(TAG,"VibratorService" );
  78. ServiceManager.addService("vibrator" , new VibratorService(context));
  79. //onlyinitializethepowerserviceafterwehavestartedthe
  80. //lightsservice,contentprovidersandthebatteryservice.
  81. power.init(context,lights,ActivityManagerService.getDefault(),battery);
  82. Slog.i(TAG,"AlarmManager" );
  83. AlarmManagerServicealarm=new AlarmManagerService(context);
  84. ServiceManager.addService(Context.ALARM_SERVICE,alarm);
  85. Slog.i(TAG,"InitWatchdog" );
  86. Watchdog.getInstance().init(context,battery,power,alarm,
  87. ActivityManagerService.self());
  88. Slog.i(TAG,"WindowManager" );
  89. wm=WindowManagerService.main(context,power,
  90. factoryTest!=SystemServer.FACTORY_TEST_LOW_LEVEL);
  91. ServiceManager.addService(Context.WINDOW_SERVICE,wm);
  92. ((ActivityManagerService)ServiceManager.getService("activity" ))
  93. .setWindowManager(wm);
  94. //SkipBluetoothifwehaveanemulatorkernel
  95. //TODO:Useamorereliablechecktoseeifthisproductshould
  96. //supportBluetooth-seebug988521
  97. if (SystemProperties.get( "ro.kernel.qemu" ).equals( "1" )){
  98. Slog.i(TAG,"RegisteringnullBluetoothService(emulator)" );
  99. ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE,null );
  100. }else if (factoryTest==SystemServer.FACTORY_TEST_LOW_LEVEL){
  101. Slog.i(TAG,"RegisteringnullBluetoothService(factorytest)" );
  102. ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE,null );
  103. }else {
  104. Slog.i(TAG,"BluetoothService" );
  105. bluetooth=new BluetoothService(context);
  106. ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE,bluetooth);
  107. bluetooth.initAfterRegistration();
  108. bluetoothA2dp=new BluetoothA2dpService(context,bluetooth);
  109. ServiceManager.addService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE,
  110. bluetoothA2dp);
  111. int bluetoothOn=Settings.Secure.getInt(mContentResolver,
  112. Settings.Secure.BLUETOOTH_ON,0 );
  113. if (bluetoothOn> 0 ){
  114. bluetooth.enable();
  115. }
  116. }
  117. }catch (RuntimeExceptione){
  118. Slog.e("System" , "Failurestartingcoreservice" ,e);
  119. }
  120. DevicePolicyManagerServicedevicePolicy=null ;
  121. StatusBarManagerServicestatusBar=null ;
  122. InputMethodManagerServiceimm=null ;
  123. AppWidgetServiceappWidget=null ;
  124. NotificationManagerServicenotification=null ;
  125. WallpaperManagerServicewallpaper=null ;
  126. LocationManagerServicelocation=null ;
  127. if (factoryTest!=SystemServer.FACTORY_TEST_LOW_LEVEL){
  128. try {
  129. Slog.i(TAG,"DevicePolicy" );
  130. devicePolicy=new DevicePolicyManagerService(context);
  131. ServiceManager.addService(Context.DEVICE_POLICY_SERVICE,devicePolicy);
  132. }catch (Throwablee){
  133. Slog.e(TAG,"FailurestartingDevicePolicyService" ,e);
  134. }
  135. try {
  136. Slog.i(TAG,"StatusBar" );
  137. statusBar=new StatusBarManagerService(context);
  138. ServiceManager.addService(Context.STATUS_BAR_SERVICE,statusBar);
  139. }catch (Throwablee){
  140. Slog.e(TAG,"FailurestartingStatusBarManagerService" ,e);
  141. }
  142. try {
  143. Slog.i(TAG,"ClipboardService" );
  144. ServiceManager.addService(Context.CLIPBOARD_SERVICE,
  145. new ClipboardService(context));
  146. }catch (Throwablee){
  147. Slog.e(TAG,"FailurestartingClipboardService" ,e);
  148. }
  149. try {
  150. Slog.i(TAG,"InputMethodService" );
  151. imm=new InputMethodManagerService(context,statusBar);
  152. ServiceManager.addService(Context.INPUT_METHOD_SERVICE,imm);
  153. }catch (Throwablee){
  154. Slog.e(TAG,"FailurestartingInputManagerService" ,e);
  155. }
  156. try {
  157. Slog.i(TAG,"NetStatService" );
  158. ServiceManager.addService("netstat" , new NetStatService(context));
  159. }catch (Throwablee){
  160. Slog.e(TAG,"FailurestartingNetStatService" ,e);
  161. }
  162. try {
  163. Slog.i(TAG,"NetworkManagementService" );
  164. ServiceManager.addService(
  165. Context.NETWORKMANAGEMENT_SERVICE,
  166. NetworkManagementService.create(context));
  167. }catch (Throwablee){
  168. Slog.e(TAG,"FailurestartingNetworkManagementService" ,e);
  169. }
  170. try {
  171. Slog.i(TAG,"ConnectivityService" );
  172. connectivity=ConnectivityService.getInstance(context);
  173. ServiceManager.addService(Context.CONNECTIVITY_SERVICE,connectivity);
  174. }catch (Throwablee){
  175. Slog.e(TAG,"FailurestartingConnectivityService" ,e);
  176. }
  177. try {
  178. Slog.i(TAG,"ThrottleService" );
  179. throttle=new ThrottleService(context);
  180. ServiceManager.addService(
  181. Context.THROTTLE_SERVICE,throttle);
  182. }catch (Throwablee){
  183. Slog.e(TAG,"FailurestartingThrottleService" ,e);
  184. }
  185. try {
  186. Slog.i(TAG,"AccessibilityManager" );
  187. ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,
  188. new AccessibilityManagerService(context));
  189. }catch (Throwablee){
  190. Slog.e(TAG,"FailurestartingAccessibilityManager" ,e);
  191. }
  192. try {
  193. /*
  194. *NotificationManagerServiceisdependantonMountService,
  195. *(formedia/usbnotifications)sowemuststartMountServicefirst.
  196. */
  197. Slog.i(TAG,"MountService" );
  198. ServiceManager.addService("mount" , new MountService(context));
  199. }catch (Throwablee){
  200. Slog.e(TAG,"FailurestartingMountService" ,e);
  201. }
  202. try {
  203. Slog.i(TAG,"NotificationManager" );
  204. notification=new NotificationManagerService(context,statusBar,lights);
  205. ServiceManager.addService(Context.NOTIFICATION_SERVICE,notification);
  206. }catch (Throwablee){
  207. Slog.e(TAG,"FailurestartingNotificationManager" ,e);
  208. }
  209. try {
  210. Slog.i(TAG,"DeviceStorageMonitor" );
  211. ServiceManager.addService(DeviceStorageMonitorService.SERVICE,
  212. new DeviceStorageMonitorService(context));
  213. }catch (Throwablee){
  214. Slog.e(TAG,"FailurestartingDeviceStorageMonitorservice" ,e);
  215. }
  216. try {
  217. Slog.i(TAG,"LocationManager" );
  218. location=new LocationManagerService(context);
  219. ServiceManager.addService(Context.LOCATION_SERVICE,location);
  220. }catch (Throwablee){
  221. Slog.e(TAG,"FailurestartingLocationManager" ,e);
  222. }
  223. try {
  224. Slog.i(TAG,"SearchService" );
  225. ServiceManager.addService(Context.SEARCH_SERVICE,
  226. new SearchManagerService(context));
  227. }catch (Throwablee){
  228. Slog.e(TAG,"FailurestartingSearchService" ,e);
  229. }
  230. if (INCLUDE_DEMO){
  231. Slog.i(TAG,"Installingdemodata..." );
  232. (new DemoThread(context)).start();
  233. }
  234. try {
  235. Slog.i(TAG,"DropBoxService" );
  236. ServiceManager.addService(Context.DROPBOX_SERVICE,
  237. new DropBoxManagerService(context, new File( "/data/system/dropbox" )));
  238. }catch (Throwablee){
  239. Slog.e(TAG,"FailurestartingDropBoxManagerService" ,e);
  240. }
  241. try {
  242. Slog.i(TAG,"WallpaperService" );
  243. wallpaper=new WallpaperManagerService(context);
  244. ServiceManager.addService(Context.WALLPAPER_SERVICE,wallpaper);
  245. }catch (Throwablee){
  246. Slog.e(TAG,"FailurestartingWallpaperService" ,e);
  247. }
  248. try {
  249. Slog.i(TAG,"AudioService" );
  250. ServiceManager.addService(Context.AUDIO_SERVICE,new AudioService(context));
  251. }catch (Throwablee){
  252. Slog.e(TAG,"FailurestartingAudioService" ,e);
  253. }
  254. try {
  255. Slog.i(TAG,"HeadsetObserver" );
  256. //Listenforwiredheadsetchanges
  257. headset=new HeadsetObserver(context);
  258. }catch (Throwablee){
  259. Slog.e(TAG,"FailurestartingHeadsetObserver" ,e);
  260. }
  261. try {
  262. Slog.i(TAG,"DockObserver" );
  263. //Listenfordockstationchanges
  264. dock=new DockObserver(context,power);
  265. }catch (Throwablee){
  266. Slog.e(TAG,"FailurestartingDockObserver" ,e);
  267. }
  268. try {
  269. Slog.i(TAG,"USBService" );
  270. //ListenforUSBchanges
  271. usb=new UsbService(context);
  272. ServiceManager.addService(Context.USB_SERVICE,usb);
  273. }catch (Throwablee){
  274. Slog.e(TAG,"FailurestartingUsbService" ,e);
  275. }
  276. try {
  277. Slog.i(TAG,"UIModeManagerService" );
  278. //ListenforUImodechanges
  279. uiMode=new UiModeManagerService(context);
  280. }catch (Throwablee){
  281. Slog.e(TAG,"FailurestartingUiModeManagerService" ,e);
  282. }
  283. try {
  284. Slog.i(TAG,"BackupService" );
  285. ServiceManager.addService(Context.BACKUP_SERVICE,
  286. new BackupManagerService(context));
  287. }catch (Throwablee){
  288. Slog.e(TAG,"FailurestartingBackupService" ,e);
  289. }
  290. try {
  291. Slog.i(TAG,"AppWidgetService" );
  292. appWidget=new AppWidgetService(context);
  293. ServiceManager.addService(Context.APPWIDGET_SERVICE,appWidget);
  294. }catch (Throwablee){
  295. Slog.e(TAG,"FailurestartingAppWidgetService" ,e);
  296. }
  297. try {
  298. Slog.i(TAG,"RecognitionService" );
  299. recognition=new RecognitionManagerService(context);
  300. }catch (Throwablee){
  301. Slog.e(TAG,"FailurestartingRecognitionService" ,e);
  302. }
  303. try {
  304. Slog.i(TAG,"DiskStatsService" );
  305. ServiceManager.addService("diskstats" , new DiskStatsService(context));
  306. }catch (Throwablee){
  307. Slog.e(TAG,"FailurestartingDiskStatsService" ,e);
  308. }
  309. }
  310. //makesuretheADB_ENABLEDsettingvaluematchesthesecurepropertyvalue
  311. Settings.Secure.putInt(mContentResolver,Settings.Secure.ADB_ENABLED,
  312. "1" .equals(SystemProperties.get( "persist.service.adb.enable" ))? 1 : 0 );
  313. //registerobservertolistenforsettingschanges
  314. mContentResolver.registerContentObserver(Settings.Secure.getUriFor(Settings.Secure.ADB_ENABLED),
  315. false , new AdbSettingsObserver());
  316. //Beforethingsstartrolling,besurewehavedecidedwhether
  317. //weareinsafemode.
  318. final boolean safeMode=wm.detectSafeMode();
  319. if (safeMode){
  320. try {
  321. ActivityManagerNative.getDefault().enterSafeMode();
  322. //PostthesafemodestateintheZygoteclass
  323. Zygote.systemInSafeMode=true ;
  324. //DisabletheJITforthesystem_serverprocess
  325. VMRuntime.getRuntime().disableJitCompilation();
  326. }catch (RemoteExceptione){
  327. }
  328. }else {
  329. //EnabletheJITforthesystem_serverprocess
  330. VMRuntime.getRuntime().startJitCompilation();
  331. }
  332. //Itisnowtimetostartuptheappprocesses...
  333. if (devicePolicy!= null ){
  334. devicePolicy.systemReady();
  335. }
  336. if (notification!= null ){
  337. notification.systemReady();
  338. }
  339. if (statusBar!= null ){
  340. statusBar.systemReady();
  341. }
  342. wm.systemReady();
  343. power.systemReady();
  344. try {
  345. pm.systemReady();
  346. }catch (RemoteExceptione){
  347. }
  348. //Theseareneededtopropagatetotherunnablebelow.
  349. final StatusBarManagerServicestatusBarF=statusBar;
  350. final BatteryServicebatteryF=battery;
  351. final ConnectivityServiceconnectivityF=connectivity;
  352. final DockObserverdockF=dock;
  353. final UsbServiceusbF=usb;
  354. final ThrottleServicethrottleF=throttle;
  355. final UiModeManagerServiceuiModeF=uiMode;
  356. final AppWidgetServiceappWidgetF=appWidget;
  357. final WallpaperManagerServicewallpaperF=wallpaper;
  358. final InputMethodManagerServiceimmF=imm;
  359. final RecognitionManagerServicerecognitionF=recognition;
  360. final LocationManagerServicelocationF=location;
  361. //Wenowtelltheactivitymanageritisokaytorunthirdparty
  362. //code.Itwillcallbackintousonceithasgottentothestate
  363. //wherethirdpartycodecanreallyrun(butbeforeithasactually
  364. //startedlaunchingtheinitialapplications),forustocompleteour
  365. //initialization.
  366. ((ActivityManagerService)ActivityManagerNative.getDefault())
  367. .systemReady(new Runnable(){
  368. public void run(){
  369. Slog.i(TAG,"Makingservicesready" );
  370. if (statusBarF!= null )statusBarF.systemReady2();
  371. if (batteryF!= null )batteryF.systemReady();
  372. if (connectivityF!= null )connectivityF.systemReady();
  373. if (dockF!= null )dockF.systemReady();
  374. if (usbF!= null )usbF.systemReady();
  375. if (uiModeF!= null )uiModeF.systemReady();
  376. if (recognitionF!= null )recognitionF.systemReady();
  377. Watchdog.getInstance().start();
  378. //Itisnowokaytoletthevarioussystemservicesstarttheir
  379. //thirdpartycode...
  380. if (appWidgetF!= null )appWidgetF.systemReady(safeMode);
  381. if (wallpaperF!= null )wallpaperF.systemReady();
  382. if (immF!= null )immF.systemReady();
  383. if (locationF!= null )locationF.systemReady();
  384. if (throttleF!= null )throttleF.systemReady();
  385. }
  386. });
  387. //Fordebugbuilds,logeventloopstallstodropboxforanalysis.
  388. if (StrictMode.conditionallyEnableDebugLogging()){
  389. Slog.i(TAG,"EnabledStrictModeforsystemservermainthread." );
  390. }
  391. Looper.loop();
  392. Slog.d(TAG,"SystemServerThreadisexiting!" );
  393. }

这里启动的没一个进程都作为一个Dalvik线程而存在于SystemServer进程里面。


Android systemserver 解析


Android systemserver 解析

Android systemserver 解析

更多相关文章

  1. Android软键盘挡住输入框的问题及解决方法
  2. Android Studio制作简易计算器源代码及详解
  3. Android 代码实现logcat输出到文件
  4. Android ColorStateList使用方法
  5. 修改android项目sdk版本的方法
  6. Android,TextView的所有属性和方法

随机推荐

  1. android之蓝牙开发续(自动配对)
  2. 讲透Python编码问题
  3. 目录间的瞬间转移术(土遁): dtags
  4. gitlab服务器部署
  5. 做一个诚信的程序员有多难?
  6. 美国围棋选手使用Python自动评级,不发段位
  7. 用Python模拟AlphaGo项目出现
  8. Swift支持ubuntu, ubuntu讨论默认Python3
  9. SpringBoot应用中使用AOP记录接口访问日
  10. libp2p-rs v0.2.0 发布