上次的Xposed
插件少个可视化界面,如果直接使用Android
开发也不是不行,但是那样太无聊了,正好试试一直想使用的React Native
技术来开发一个简单的界面。
开发工具同样是简单的Android Studio
,按照RN
中文网上的开发步骤先搭建一个Hello World
,基于这个demo
先做一个不读取数据的展示页面,顺便学习一下导航栏的使用。
RN 与原生的数据交互是通过NativeModules
这个对象进行异步操作的,可以通过async
和await
使操作更简单,并封装一个调用原生的方法
1 2 3 4 5 import { NativeModules } from 'react-native' ;export async function JsDBHelperCall (func, ...args ) { return await NativeModules.JsDBHelper[func](...args); }
简单的应用里也无需使用redux
来管理数据,直接使用Props
传递即可,其他的代码基本和写React
一样,然后运行起来并写好java
端的代码,实现数据流通便算完成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 public class JsDBHelper extends ReactContextBaseJavaModule { private DBHelper db = null ; private SportEditorDao sportEditorDao = null ; public JsDBHelper (ReactApplicationContext reactContext) { super (reactContext); db = new DBHelper(reactContext); sportEditorDao = new SportEditorDao(reactContext); } @Override public String getName () { return this .getClass().getSimpleName(); } @ReactMethod public void ExecSQL (String sql, ReadableArray selectionArgs) { try { JSONArray args = ArrayUtil.toJSONArray(selectionArgs); db.ExecSQL(sql, args.toJavaList(String.class)); } catch (JSONException e) { e.printStackTrace(); } } @ReactMethod public void QueryForMap (String sql, ReadableArray selectionArgs) { try { JSONArray args = ArrayUtil.toJSONArray(selectionArgs); Map<String, String> result = db.QueryForMap(sql, args.toJavaList(String.class)); } catch (JSONException e) { e.printStackTrace(); } } @ReactMethod public void QueryForListMap (String sql, ReadableArray selectionArgs, Promise promise) { ... } @ReactMethod public void GetConfigByPackageName (String packageName, Promise promise) { ... } @ReactMethod public void GetConfigs (Promise promise) { ... } @ReactMethod public void SaveConfig (ReadableMap selectionArgs, Promise promise) { ... } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 export default class HomeScreen extends React .PureComponent { constructor (props ) { super (props); this .state = { configs : Immutable.fromJS([]), refreshing : false , isLoading : true , }; this .onRefresh = this .onRefresh.bind(this ); this .rowClick = this .rowClick.bind(this ); } async componentDidMount ( ) { let configs = await JsDBHelperCall('GetConfigs' ); this .setState({ isLoading : false , configs : Immutable.fromJS(configs), }); console .log(configs); } async onRefresh ( ) { this .setState({ refreshing : true , }); let configs = await JsDBHelperCall('GetConfigs' ); this .setState({ refreshing : false , configs : Immutable.fromJS(configs), }); console .log(configs); } rowClick (config, index ) { this .props.navigation.navigate('Detail' , { config : config, callBack : this .onRefresh, }); } render ( ) { const emptyText = this .state.isLoading ? 'Loading...' : this .state.errorMsg ? 'Error!' : 'No data.' ; return ( <View > <ImmutableVirtualizedList immutableData ={this.state.configs} keyExtractor ={(item, index ) => item.get('packageName')} ListHeaderComponent={() => <AppRowHeader /> } renderItem={({ item, index }) => <AppRow config ={item} rowClick ={this.rowClick} index ={index} /> } onRefresh={this.onRefresh} refreshing={this.state.refreshing} renderEmptyInList={emptyText} /> </View > ); } }
然后再将原来的Xposed APP
代码原样移植到这边的java
层,丢到手机运行,收工!
这个插件如果有需要也可以自由下载代码 编译,个人比较懒,也不想发布到Xposed
市场里。