拷贝APP_Bck20250119项目源码,移除libjc/jcc/libs/android-29.jar文件。
This commit is contained in:
		
							
								
								
									
										6
									
								
								libjc/.classpath
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								libjc/.classpath
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <classpath> | ||||
| 	<classpathentry kind="src" path="src"/> | ||||
| 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.7.0_45"/> | ||||
| 	<classpathentry kind="output" path="bin"/> | ||||
| </classpath> | ||||
							
								
								
									
										1
									
								
								libjc/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								libjc/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| /build | ||||
							
								
								
									
										17
									
								
								libjc/.project
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								libjc/.project
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <projectDescription> | ||||
| 	<name>$project_name$</name> | ||||
| 	<comment></comment> | ||||
| 	<projects> | ||||
| 	</projects> | ||||
| 	<buildSpec> | ||||
| 		<buildCommand> | ||||
| 			<name>org.eclipse.jdt.core.javabuilder</name> | ||||
| 			<arguments> | ||||
| 			</arguments> | ||||
| 		</buildCommand> | ||||
| 	</buildSpec> | ||||
| 	<natures> | ||||
| 		<nature>org.eclipse.jdt.core.javanature</nature> | ||||
| 	</natures> | ||||
| </projectDescription> | ||||
							
								
								
									
										4
									
								
								libjc/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								libjc/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| ## LIBJC | ||||
| ### Java console Library | ||||
| ### It design JC,JCNDK project. | ||||
| ### And the Unit Test Console is jcc project which is place in libjc. | ||||
							
								
								
									
										33
									
								
								libjc/build.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								libjc/build.gradle
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| apply plugin: 'com.android.library' | ||||
|  | ||||
| android { | ||||
|     //compileSdkVersion 21 | ||||
|     //buildToolsVersion "21.1.0" | ||||
|     compileSdkVersion 32 | ||||
|     buildToolsVersion "33.0.3" | ||||
|  | ||||
|     defaultConfig { | ||||
|         //applicationId "cc.winboll.studio.libjc" | ||||
|         //minSdkVersion 14 | ||||
|         //targetSdkVersion 21 | ||||
|         minSdkVersion 24 | ||||
|         targetSdkVersion 29 | ||||
|         versionCode 1 | ||||
|         versionName "1.0" | ||||
|     } | ||||
|     buildTypes { | ||||
|         release { | ||||
|             minifyEnabled false | ||||
|             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| dependencies { | ||||
|     // https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on | ||||
|     //implementation 'org.bouncycastle:bcprov-jdk15on:1.70' | ||||
|     implementation 'org.bouncycastle:bcprov-jdk15to18:1.69' | ||||
|     implementation 'org.bouncycastle:bcpkix-jdk15to18:1.69' | ||||
|  | ||||
|     api fileTree(dir: 'libs', include: ['*.jar']) | ||||
| } | ||||
							
								
								
									
										8
									
								
								libjc/build.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								libjc/build.properties
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| #Created by .winboll/winboll_app_build.gradle | ||||
| #Fri Jan 10 22:03:57 GMT 2025 | ||||
| stageCount=0 | ||||
| libraryProject=libjc | ||||
| baseVersion=1.0 | ||||
| publishVersion=1.0.0 | ||||
| buildCount=133 | ||||
| baseBetaVersion=1.0.1 | ||||
							
								
								
									
										6
									
								
								libjc/jcc/.classpath
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								libjc/jcc/.classpath
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <classpath> | ||||
| 	<classpathentry kind="src" path="../src"/> | ||||
| 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.7.0_45"/> | ||||
| 	<classpathentry kind="output" path="bin"/> | ||||
| </classpath> | ||||
							
								
								
									
										1
									
								
								libjc/jcc/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								libjc/jcc/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| /output_jars | ||||
							
								
								
									
										17
									
								
								libjc/jcc/.project
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								libjc/jcc/.project
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <projectDescription> | ||||
| 	<name>$project_name$</name> | ||||
| 	<comment></comment> | ||||
| 	<projects> | ||||
| 	</projects> | ||||
| 	<buildSpec> | ||||
| 		<buildCommand> | ||||
| 			<name>org.eclipse.jdt.core.javabuilder</name> | ||||
| 			<arguments> | ||||
| 			</arguments> | ||||
| 		</buildCommand> | ||||
| 	</buildSpec> | ||||
| 	<natures> | ||||
| 		<nature>org.eclipse.jdt.core.javanature</nature> | ||||
| 	</natures> | ||||
| </projectDescription> | ||||
							
								
								
									
										3
									
								
								libjc/jcc/MANIFEST.MF
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								libjc/jcc/MANIFEST.MF
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| Manifest-Version: 1.0 | ||||
| Class-Path: . | ||||
| Main-Class: cc.winboll.studio.libjc.Main | ||||
							
								
								
									
										40
									
								
								libjc/jcc/bash_build_jar.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								libjc/jcc/bash_build_jar.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| #!/usr/bin/bash | ||||
| ## 跳转到 libjc 项目目录查找源码文件夹 src 和编译环境目录 jcc 目录,如果两个目录其中一个不存在就退出 | ||||
| cd .. | ||||
|  | ||||
| ## 记录当前工作目录 | ||||
| workpath=$(pwd) | ||||
|  | ||||
| ## 检查源码目录与 jcc 工作目录 | ||||
| srcdir="src" | ||||
| if [ -d "${srcdir}" ]; then | ||||
|     echo "Src dir ${srcdir} found." | ||||
| else | ||||
|     echo "Src dir ${srcdir} not exist." | ||||
|     exit 1 | ||||
| fi | ||||
| jccdir="jcc" | ||||
| if [ -d "${jccdir}" ]; then | ||||
|     echo "Jcc dir ${jccdir} found." | ||||
| else | ||||
|     echo "Jcc dir ${jccdir} not exist." | ||||
|     exit 1 | ||||
| fi | ||||
|  | ||||
| jarversion="1.0.1" | ||||
| jarname="libjc-"${jarversion}".jar" | ||||
| classespath="${workpath}/${jccdir}/classes" | ||||
| jarspath="${workpath}/${jccdir}/output_jars" | ||||
| srcpath="${workpath}/${srcdir}/main/java" | ||||
| libspath="${workpath}/${jccdir}/libs" | ||||
|  | ||||
| echo "Gen class to "${classespath}" :" | ||||
| cd ${srcpath} | ||||
| javac -cp ".:${libspath}/android-29.jar"  -d ${classespath} $(find . -name "*.java") | ||||
| echo "Build "${jarname}" :" | ||||
| cd ${classespath}; | ||||
| jar -cvfm ${jarspath}/${jarname} ${workpath}/${jccdir}/MANIFEST.MF cc | ||||
| echo "Jar Build OK." | ||||
|  | ||||
| cd .. | ||||
| bash test_jar.sh ${jarversion} | ||||
							
								
								
									
										10
									
								
								libjc/jcc/src/Main.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								libjc/jcc/src/Main.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| //import java.util.*; | ||||
| // | ||||
| //public class Main { | ||||
| //	 | ||||
| //	public static void main(String[] args) { | ||||
| //		System.out.println("Hello World!"); | ||||
| //         | ||||
| //    } | ||||
| //     | ||||
| //} | ||||
							
								
								
									
										26
									
								
								libjc/jcc/test_jar.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								libjc/jcc/test_jar.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| #!/usr/bin/bash | ||||
| jarversion=$1 | ||||
| jarname="libjc-"${jarversion}".jar" | ||||
|  | ||||
| cd output_jars | ||||
|  | ||||
| echo -e "\nTest "${jarname}" Main :" | ||||
| java -jar ${jarname} "UnitTest" | ||||
|  | ||||
| testclass="TestClassA" | ||||
| echo -e "\nTest "${jarname}" ${testclass} :" | ||||
| echo -e "Test 1 :" | ||||
| java -cp ${jarname} cc.winboll.studio.libjc.${testclass} | ||||
| echo -e "Test 2 :<Test>" | ||||
| java -cp ${jarname} cc.winboll.studio.libjc.${testclass} "Test" | ||||
| echo -e "Test 3 :<UnitTest>" | ||||
| java -cp ${jarname} cc.winboll.studio.libjc.${testclass} "UnitTest" | ||||
|  | ||||
| testclass="TestClassB" | ||||
| echo -e "\nTest "${jarname}" ${testclass} :" | ||||
| echo "Test 1 :" | ||||
| java -cp ${jarname} cc.winboll.studio.libjc.${testclass} | ||||
| echo -e "Test 2 :<Test>" | ||||
| java -cp ${jarname} cc.winboll.studio.libjc.${testclass} "Test" | ||||
| echo -e "Test 3 :<UnitTest>" | ||||
| java -cp ${jarname} cc.winboll.studio.libjc.${testclass} "UnitTest" | ||||
							
								
								
									
										17
									
								
								libjc/proguard-rules.pro
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								libjc/proguard-rules.pro
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| # Add project specific ProGuard rules here. | ||||
| # By default, the flags in this file are appended to flags specified | ||||
| # in C:/tools/adt-bundle-windows-x86_64-20131030/sdk/tools/proguard/proguard-android.txt | ||||
| # You can edit the include path and order by changing the proguardFiles | ||||
| # directive in build.gradle. | ||||
| # | ||||
| # For more details, see | ||||
| #   http://developer.android.com/guide/developing/tools/proguard.html | ||||
|  | ||||
| # Add any project specific keep options here: | ||||
|  | ||||
| # If your project uses WebView with JS, uncomment the following | ||||
| # and specify the fully qualified class name to the JavaScript interface | ||||
| # class: | ||||
| #-keepclassmembers class fqcn.of.javascript.interface.for.webview { | ||||
| #   public *; | ||||
| #} | ||||
							
								
								
									
										14
									
								
								libjc/src/main/AndroidManifest.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								libjc/src/main/AndroidManifest.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     package="cc.winboll.studio.libjc" | ||||
|     android:sharedUserId="com.termux"> | ||||
|  | ||||
|     <application> | ||||
|         <activity | ||||
|             android:name=".LibraryActivity" | ||||
|             android:label="@string/lib_name" > | ||||
|         </activity> | ||||
|     </application> | ||||
|  | ||||
| </manifest> | ||||
|  | ||||
							
								
								
									
										160
									
								
								libjc/src/main/java/cc/winboll/studio/libjc/JCCommandThread.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								libjc/src/main/java/cc/winboll/studio/libjc/JCCommandThread.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,160 @@ | ||||
| package cc.winboll.studio.libjc; | ||||
|  | ||||
| /** | ||||
|  * @Author ZhanGSKen@QQ.COM | ||||
|  * @Date 2025/01/07 17:34:56 | ||||
|  * @Describe JC命令行执行类 | ||||
|  */ | ||||
| import cc.winboll.studio.libjc.util.LogUtils; | ||||
| import java.io.BufferedReader; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.io.InputStreamReader; | ||||
| import java.io.OutputStream; | ||||
|  | ||||
| public class JCCommandThread extends Thread { | ||||
|     //static volatile JCCommandThread _JCCommandThread; | ||||
|     public JCCommandThread() {} | ||||
| //    public static synchronized JCCommandThread getInstance() { | ||||
| //        if(_JCCommandThread == null) { | ||||
| //            _JCCommandThreadRunning = false; | ||||
| //            _JCCommandThread = new JCCommandThread(); | ||||
| //        } | ||||
| //        return _JCCommandThread; | ||||
| //    } | ||||
| //     | ||||
|     static volatile String _CMD; | ||||
|     static volatile boolean _Exit; | ||||
|     static volatile boolean _JCCommandThreadRunning; | ||||
|     static Process _Process; | ||||
|  | ||||
|     public static final String TAG = "JCCommand"; | ||||
|  | ||||
|     public synchronized void exec(String cmd) { | ||||
|         if (cmd.equals("/bye")) { | ||||
|             _Exit = true; | ||||
|             return; | ||||
|         } else if (_CMD.equals("") && !cmd.equals("")) { | ||||
|             _CMD = cmd + "\n"; | ||||
|             OutputStream outputStream = _Process.getOutputStream(); | ||||
|             try { | ||||
|                 System.out.println("$ " + _CMD); | ||||
|                 //Log.d(TAG, "_CMD : " + _CMD); | ||||
|                 outputStream.write(_CMD.getBytes()); | ||||
|                 outputStream.flush(); | ||||
|                 _CMD = ""; | ||||
|                 //Log.d(TAG, "OutputStream done."); | ||||
|             } catch (IOException e) { | ||||
|                 LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void run() { | ||||
|         super.run(); | ||||
|         if(!_JCCommandThreadRunning) { | ||||
|             _JCCommandThreadRunning = true; | ||||
|             init(); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     public void init() { | ||||
|         _Exit = false; | ||||
|         _CMD = ""; | ||||
|         try { | ||||
|             LogUtils.d(TAG, "start()"); | ||||
|             _Process = Runtime.getRuntime().exec("/system/xbin/busybox ash"); | ||||
|  | ||||
|             // 创建线程读取标准输出流 | ||||
|             OutputThread outputThread = new OutputThread(); | ||||
|             //outputThread.initProcess(_Process); | ||||
|  | ||||
|             // 创建线程读取标准错误流(通常命令执行出错的信息会在这里输出) | ||||
|             ErrorThread errorThread = new ErrorThread(); | ||||
|             //outputThread.initProcess(_Process); | ||||
|  | ||||
|             LogUtils.d(TAG, "Process init ok."); | ||||
|             outputThread.start(); | ||||
|             errorThread.start(); | ||||
|             LogUtils.d(TAG, "Thread start."); | ||||
|  | ||||
| //            while (!_Exit) { | ||||
| //                exec(); | ||||
| //            } | ||||
|  | ||||
|             // 等待线程执行完毕 | ||||
| //            try { | ||||
| //                outputThread.join(); | ||||
| //                errorThread.join(); | ||||
| //                Log.d(TAG, "Thread join."); | ||||
| //            } catch (InterruptedException e) { | ||||
| //                Log.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
| //            } | ||||
|  | ||||
|             // 等待命令执行结束并获取退出值 | ||||
|             LogUtils.d(TAG, "_Process.waitFor()"); | ||||
|             int exitValue = _Process.waitFor(); | ||||
|             LogUtils.d(TAG, "Process exited with value: " + exitValue); | ||||
|  | ||||
|             _Exit = true; | ||||
|  | ||||
|         } catch (IOException | InterruptedException e) { | ||||
|             LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static class OutputThread extends Thread { | ||||
| //        java.lang.Process mProcess; | ||||
| //        public void initProcess(java.lang.Process process) { | ||||
| //            mProcess = process; | ||||
| //        } | ||||
|         @Override | ||||
|         public void run() { | ||||
|             super.run(); | ||||
|             try { | ||||
|                 InputStream inputStream = _Process.getInputStream(); | ||||
|                 BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); | ||||
|                 String line; | ||||
|                 while ((line = reader.readLine()) != null) { | ||||
|                     System.out.println(line); | ||||
|                     //Log.d(TAG, line); | ||||
|                 } | ||||
|                 reader.close(); | ||||
|                 inputStream.close(); | ||||
|             } catch (IOException e) { | ||||
|                 e.printStackTrace(); | ||||
|                 LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     public static class ErrorThread extends Thread { | ||||
| //        java.lang.Process mProcess; | ||||
| //        public void initProcess(java.lang.Process process) { | ||||
| //            mProcess = process; | ||||
| //        } | ||||
|  | ||||
|         @Override | ||||
|         public void run() { | ||||
|             super.run(); | ||||
|             try { | ||||
|                 InputStream errorStream = _Process.getErrorStream(); | ||||
|                 BufferedReader errorReader = new BufferedReader(new InputStreamReader(errorStream)); | ||||
|                 String line; | ||||
|                 while ((line = errorReader.readLine()) != null) { | ||||
|                     System.out.println("Error: " + line); | ||||
|                     //Log.d(TAG, "Error: " + line); | ||||
|                 } | ||||
|                 errorReader.close(); | ||||
|                 errorStream.close(); | ||||
|             } catch (IOException e) { | ||||
|                 e.printStackTrace(); | ||||
|                 LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -0,0 +1,84 @@ | ||||
| package cc.winboll.studio.libjc; | ||||
|  | ||||
| /** | ||||
|  * @Author ZhanGSKen@QQ.COM | ||||
|  * @Date 2025/01/07 13:46:40 | ||||
|  * @Describe JC 错误输出流 | ||||
|  */ | ||||
| import cc.winboll.studio.libjc.util.LogUtils; | ||||
| import java.io.IOException; | ||||
| import java.io.OutputStream; | ||||
| import java.io.PrintStream; | ||||
|  | ||||
| public class JCErrorStream extends OutputStream { | ||||
|  | ||||
|     public static final String TAG = "JCErrorStream"; | ||||
|     private StringBuilder buffer = new StringBuilder(); | ||||
|  | ||||
|     static volatile JCErrorStream _JCErrorStream; | ||||
|     static volatile boolean _IsInitOK; | ||||
|     JCMainThread.OnMessageListener mOnMessageListener; | ||||
|  | ||||
|     @Override | ||||
|     public void write(int b) { | ||||
|         buffer.append((char) b); | ||||
|         err(String.format("%i", b)); | ||||
|     } | ||||
|  | ||||
|     void err(String message) { | ||||
|         mOnMessageListener.errPrint(message); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void write(byte[] b, int off, int len) { | ||||
|         buffer.append(new String(b, off, len)); | ||||
|         err(new String(b, off, len)); | ||||
|     } | ||||
|  | ||||
|     public String getOutput() { | ||||
|         return buffer.toString(); | ||||
|     } | ||||
|     JCErrorStream(JCMainThread.OnMessageListener listener) { | ||||
|         mOnMessageListener = listener; | ||||
|     } | ||||
|  | ||||
|     public static void start(JCMainThread.OnMessageListener listener) { | ||||
|         LogUtils.d(TAG, String.format("%s init()\n", TAG)); | ||||
|  | ||||
|         if (_JCErrorStream == null) { | ||||
|             _JCErrorStream = new JCErrorStream(listener); | ||||
|             _IsInitOK = false; | ||||
|  | ||||
|             // 保存原始的System.out | ||||
|             PrintStream originalOut = System.err; | ||||
|             try { | ||||
|                 // 创建自定义输出流实例并将System.out重定向到它 | ||||
|                 //JCOutputStream jcOutputStream = new JCOutputStream(); | ||||
|                 System.setErr(new PrintStream(_JCErrorStream)); | ||||
|                 System.err.println("Test err stream.\n"); | ||||
|                 while (!JCMainThread._Exit) { | ||||
|                      | ||||
|                 } | ||||
|                 // 这里原本输出到控制台的内容会被重定向到自定义输出流 | ||||
|                 System.out.println("这是被接管后输出的内容"); | ||||
|                 System.out.println("另一行内容"); | ||||
|  | ||||
|                 // 获取自定义输出流收集到的内容 | ||||
|                 String output = _JCErrorStream.getOutput(); | ||||
|                 System.out.println("收集到的内容: " + output); | ||||
|  | ||||
|                 // 恢复System.out为原始的输出流 | ||||
|                 System.setOut(originalOut); | ||||
|  | ||||
|  | ||||
|             } finally { | ||||
|                 try { | ||||
|                     _JCErrorStream.close(); | ||||
|                 } catch (IOException e) { | ||||
|                     LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -0,0 +1,22 @@ | ||||
| package cc.winboll.studio.libjc; | ||||
|  | ||||
| /** | ||||
|  * @Author ZhanGSKen@QQ.COM | ||||
|  * @Date 2025/01/07 13:51:14 | ||||
|  * @Describe 错误输出流进程 | ||||
|  */ | ||||
| public class JCErrorThread extends Thread { | ||||
|  | ||||
|     public static final String TAG = "JCErrorThread"; | ||||
|  | ||||
|     JCMainThread.OnMessageListener mOnMessageListener; | ||||
|  | ||||
|     public JCErrorThread(JCMainThread.OnMessageListener listener) { | ||||
|         mOnMessageListener = listener; | ||||
|     } | ||||
|     @Override | ||||
|     public void run() { | ||||
|         super.run(); | ||||
|         JCErrorStream.start(mOnMessageListener); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										101
									
								
								libjc/src/main/java/cc/winboll/studio/libjc/JCMainThread.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								libjc/src/main/java/cc/winboll/studio/libjc/JCMainThread.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| package cc.winboll.studio.libjc; | ||||
|  | ||||
| import cc.winboll.studio.libjc.JCMainThread; | ||||
| import cc.winboll.studio.libjc.util.ConsoleUtils; | ||||
| import cc.winboll.studio.libjc.util.LogUtils; | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.util.Date; | ||||
|  | ||||
| public class JCMainThread extends Thread { | ||||
|  | ||||
|     public static String TAG = "JCMainThread"; | ||||
|  | ||||
|     static volatile JCMainThread _JCMainThread; | ||||
|     static volatile boolean _Exit; | ||||
|     static OnMessageListener _OnLogListener; | ||||
|     JCCommandThread mJCCommand; | ||||
|  | ||||
|     JCMainThread(String logName) { | ||||
| 		ConsoleUtils.Debug.printFuncInfo(TAG); | ||||
| 		 | ||||
|         _Exit = false; | ||||
|         _OnLogListener = null; | ||||
| 		 | ||||
|         LogUtils.init((logName == null || logName.equals("")) ?JCMainThread.class.getName(): logName); | ||||
|         System.out.println("JCMainThread()"); | ||||
|         LogUtils.d(TAG, "JCMainThread()"); | ||||
|  | ||||
|         Main.setRunningMode(Main.JAR_RUNNING_MODE.CONSOLE); | ||||
|     } | ||||
|  | ||||
|     public static synchronized JCMainThread getInstance(String logName) { | ||||
|         if (_JCMainThread == null) { | ||||
|             _JCMainThread = new JCMainThread(logName); | ||||
|         } | ||||
|         return _JCMainThread; | ||||
|     } | ||||
|      | ||||
|      | ||||
|  | ||||
|     public void exeInit(String cmd) { | ||||
|         //System.out.println("cmd " + cmd); | ||||
|         mJCCommand.exec(cmd); | ||||
|     } | ||||
|  | ||||
|     public void exeBashCommand(String cmd) { | ||||
|         //System.out.println("cmd " + cmd); | ||||
|         mJCCommand.exec(cmd); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void run() { | ||||
|         super.run(); | ||||
| 		System.out.println("JCMainThread run()"); | ||||
|         LogUtils.d(TAG, "run()"); | ||||
|         if (_OnLogListener != null) { | ||||
|             (new JCErrorThread(_OnLogListener)).start(); | ||||
|             (new JCOutputThread(_OnLogListener)).start(); | ||||
|         } | ||||
|         mJCCommand = new JCCommandThread(); | ||||
|         mJCCommand.start(); | ||||
|  | ||||
|         while (!_Exit) { | ||||
|  | ||||
|             //Log.d(TAG, "!_Exit"); | ||||
|             Date date = new Date(); | ||||
|             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | ||||
|             String formattedDate = sdf.format(date); | ||||
|             String msg = String.format("run() %s", formattedDate); | ||||
|             //System.out.println(msg); | ||||
|             //System.err.println("err : " + msg); | ||||
|             try { | ||||
|                 Thread.sleep(5 * 1000); | ||||
|  | ||||
|                 // 这里模拟一下运行出错 | ||||
| //                String[] as = new String[2]; | ||||
| //                String b = as[3]; | ||||
| //                System.out.println(b); | ||||
| // | ||||
|             } catch (Exception e) { | ||||
|                 LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|             } | ||||
|         } | ||||
| 		System.out.println("JCMainThread run()"); | ||||
|         // 内存清理 | ||||
|         _OnLogListener = null; | ||||
|     } | ||||
|  | ||||
|     public static OnMessageListener getOnLogListener() { | ||||
|         return _OnLogListener; | ||||
|     } | ||||
|  | ||||
|     public static void setOnLogListener(OnMessageListener listener) { | ||||
|         _OnLogListener = listener; | ||||
|     } | ||||
|  | ||||
|     public interface OnMessageListener { | ||||
|         //void log(String message); | ||||
|         void outPrint(String message); | ||||
|         void errPrint(String message); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,84 @@ | ||||
| package cc.winboll.studio.libjc; | ||||
|  | ||||
| /** | ||||
|  * @Author ZhanGSKen@QQ.COM | ||||
|  * @Date 2025/01/07 12:32:19 | ||||
|  * @Describe 控制台输出流接口类 | ||||
|  */ | ||||
| import cc.winboll.studio.libjc.util.LogUtils; | ||||
| import java.io.IOException; | ||||
| import java.io.OutputStream; | ||||
| import java.io.PrintStream; | ||||
|  | ||||
| public class JCOutputStream extends OutputStream { | ||||
|  | ||||
|     public static final String TAG = "JCOutputStream"; | ||||
|     private StringBuilder buffer = new StringBuilder(); | ||||
|  | ||||
|     static volatile JCOutputStream _JCOutputStream; | ||||
|     static volatile boolean _IsInitOK; | ||||
|     JCMainThread.OnMessageListener mOnMessageListener; | ||||
|  | ||||
|     @Override | ||||
|     public void write(int b) { | ||||
|         buffer.append((char) b); | ||||
|         print(String.format("%i", b)); | ||||
|     } | ||||
|  | ||||
|     void print(String message) { | ||||
|         mOnMessageListener.outPrint(message); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void write(byte[] b, int off, int len) { | ||||
|         buffer.append(new String(b, off, len)); | ||||
|         print(new String(b, off, len)); | ||||
|     } | ||||
|  | ||||
|     public String getOutput() { | ||||
|         return buffer.toString(); | ||||
|     } | ||||
|     JCOutputStream(JCMainThread.OnMessageListener listener) { | ||||
|         mOnMessageListener = listener; | ||||
|     } | ||||
|  | ||||
|     public static void start(JCMainThread.OnMessageListener listener) { | ||||
|         LogUtils.d(TAG, String.format("%s init()\n", TAG)); | ||||
|  | ||||
|         if (_JCOutputStream == null) { | ||||
|             _JCOutputStream = new JCOutputStream(listener); | ||||
|             _IsInitOK = false; | ||||
|  | ||||
|             // 保存原始的System.out | ||||
|             PrintStream originalOut = System.out; | ||||
|             try { | ||||
|                 // 创建自定义输出流实例并将System.out重定向到它 | ||||
|                 //JCOutputStream jcOutputStream = new JCOutputStream(); | ||||
|                 System.setOut(new PrintStream(_JCOutputStream)); | ||||
|                 System.out.println("Test out stream.\n"); | ||||
|                 while (!JCMainThread._Exit) { | ||||
|                      | ||||
|                 } | ||||
|                 // 这里原本输出到控制台的内容会被重定向到自定义输出流 | ||||
|                 System.out.println("这是被接管后输出的内容"); | ||||
|                 System.out.println("另一行内容"); | ||||
|  | ||||
|                 // 获取自定义输出流收集到的内容 | ||||
|                 String output = _JCOutputStream.getOutput(); | ||||
|                 System.out.println("收集到的内容: " + output); | ||||
|  | ||||
|                 // 恢复System.out为原始的输出流 | ||||
|                 System.setOut(originalOut); | ||||
|  | ||||
|  | ||||
|             } finally { | ||||
|                 try { | ||||
|                     _JCOutputStream.close(); | ||||
|                 } catch (IOException e) { | ||||
|                     LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -0,0 +1,22 @@ | ||||
| package cc.winboll.studio.libjc; | ||||
|  | ||||
| /** | ||||
|  * @Author ZhanGSKen@QQ.COM | ||||
|  * @Date 2025/01/07 13:27:26 | ||||
|  * @Describe JC输出流进程 | ||||
|  */ | ||||
| public class JCOutputThread extends Thread { | ||||
|      | ||||
|     public static final String TAG = "JCOutputThread"; | ||||
|      | ||||
|     JCMainThread.OnMessageListener mOnMessageListener; | ||||
|  | ||||
|     public JCOutputThread(JCMainThread.OnMessageListener listener) { | ||||
|         mOnMessageListener = listener; | ||||
|     } | ||||
|     @Override | ||||
|     public void run() { | ||||
|         super.run(); | ||||
|         JCOutputStream.start(mOnMessageListener); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										136
									
								
								libjc/src/main/java/cc/winboll/studio/libjc/Main.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								libjc/src/main/java/cc/winboll/studio/libjc/Main.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,136 @@ | ||||
| package cc.winboll.studio.libjc; | ||||
|  | ||||
| import cc.winboll.studio.libjc.Main; | ||||
| import cc.winboll.studio.libjc.cmd.ListJarClassHasMain; | ||||
| import cc.winboll.studio.libjc.net.JCSocketServer; | ||||
| import java.util.Scanner; | ||||
|  | ||||
| public class Main { | ||||
|  | ||||
|     public final static String TAG = "Main"; | ||||
|  | ||||
|     /** | ||||
|      * @Author ZhanGSKen@QQ.COM | ||||
|      * @Date 2025/01/09 17:03:50 | ||||
|      * @Describe 当前源码实例的运行模式。 | ||||
|      */ | ||||
|     public final static int JAR_RUNNING_MODE_UNKNOWN = 0; | ||||
|     public final static int JAR_RUNNING_MODE_CONSOLE = 1; | ||||
|     public final static int JAR_RUNNING_MODE_CONSOLE_DEBUG = 2; | ||||
|     public final static int JAR_RUNNING_MODE_JCNDK = 3; | ||||
|     public final static int JAR_RUNNING_MODE_JCNDK_DEBUG = 4; | ||||
|     public final static int JAR_RUNNING_MODE_JC = 5; | ||||
|     public final static int JAR_RUNNING_MODE_JC_DEBUG = 6; | ||||
|     public enum JAR_RUNNING_MODE { | ||||
|         UNKNOWN(JAR_RUNNING_MODE_UNKNOWN), | ||||
|         CONSOLE(JAR_RUNNING_MODE_CONSOLE), | ||||
|         CONSOLE_DEBUG(JAR_RUNNING_MODE_CONSOLE_DEBUG), | ||||
|         JCNDK(JAR_RUNNING_MODE_JCNDK), | ||||
|         JCNDK_DEBUG(JAR_RUNNING_MODE_JCNDK_DEBUG), | ||||
|         JC(JAR_RUNNING_MODE_JC), | ||||
|         JC_DEBUG(JAR_RUNNING_MODE_JC_DEBUG); | ||||
|         static String[] _mlistName = { | ||||
|             "未知模式", | ||||
|             "控制台", | ||||
|             "控制台调试", | ||||
|             "JCNDK", | ||||
|             "JCNDK_DEBUG", | ||||
|             "JC", | ||||
|             "JC_DEBUG"}; | ||||
|         private int value = 0; | ||||
|         private JAR_RUNNING_MODE(int value) {    //必须是private的,否则编译错误 | ||||
|             this.value = value; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static volatile boolean _DEBUG = true; //调试标志 | ||||
|     static volatile JAR_RUNNING_MODE _JAR_RUNNING_MODE = JAR_RUNNING_MODE.UNKNOWN; | ||||
|  | ||||
|     static UserInputThread _UserInputThread; | ||||
|     static JCMainThread _JCMainThread; | ||||
|  | ||||
| 	static JCSocketServer _SocketServer; | ||||
|  | ||||
| 	public static void setDebug(boolean isDebug) { | ||||
| 		_DEBUG = isDebug; | ||||
| 	} | ||||
|  | ||||
| 	public static boolean isDebug() { | ||||
| 		return _DEBUG; | ||||
| 	} | ||||
|  | ||||
|     public static void setRunningMode(JAR_RUNNING_MODE mode) { | ||||
|         _JAR_RUNNING_MODE = mode; | ||||
|         switch (_JAR_RUNNING_MODE.ordinal()) { | ||||
|             case JAR_RUNNING_MODE_CONSOLE_DEBUG:  | ||||
|             case JAR_RUNNING_MODE_JCNDK_DEBUG: | ||||
|             case JAR_RUNNING_MODE_JC_DEBUG: { | ||||
|                     setDebug(true); | ||||
|                     break; | ||||
|                 } | ||||
|             default : { | ||||
|                     setDebug(false); | ||||
|                     break; | ||||
|                 } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static JAR_RUNNING_MODE getRunningMode() { | ||||
|         return _JAR_RUNNING_MODE; | ||||
|     } | ||||
|  | ||||
|     public static void main(String[] args) { | ||||
|         System.out.println("Hello World!"); | ||||
| 		System.out.println(String.format("%s Start", TAG)); | ||||
|  | ||||
|         Scanner scanner = new Scanner(System.in); | ||||
|         System.out.println("是否进入调试状态?(请输入yes或其他内容)"); | ||||
|         String input = scanner.nextLine(); | ||||
|         if ("yes".equalsIgnoreCase(input)) { | ||||
|             //System.out.println("OK"); | ||||
|             Main.setRunningMode(Main.JAR_RUNNING_MODE.CONSOLE_DEBUG); | ||||
|         } else { | ||||
|             Main.setRunningMode(Main.JAR_RUNNING_MODE.CONSOLE); | ||||
|         } | ||||
|         scanner.close(); | ||||
|  | ||||
|         //Main.setRunningMode(Main.JAR_RUNNING_MODE.CONSOLE); | ||||
|         //Main.setRunningMode(Main.JAR_RUNNING_MODE.CONSOLE_DEBUG); | ||||
|  | ||||
|         try { | ||||
|             if (args.length > 0 && args[0].equals("UnitTest")) { | ||||
|                 System.out.println(TestClassA.hello()); | ||||
|                 System.out.println(TestClassB.hello()); | ||||
|             } else { | ||||
|                 _JCMainThread = JCMainThread.getInstance(Main.class.getName()); | ||||
|                 _JCMainThread.start(); | ||||
|  | ||||
|                 _SocketServer = JCSocketServer.getInstance(); | ||||
|                 _SocketServer.main(null); | ||||
|  | ||||
|                 _UserInputThread = new UserInputThread(); | ||||
|                 _UserInputThread.start(); | ||||
|  | ||||
|                 ListJarClassHasMain.main(null); | ||||
|             } | ||||
|         } catch (Exception e) { | ||||
|             System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     static class UserInputThread extends Thread { | ||||
|  | ||||
|         @Override | ||||
|         public void run() { | ||||
|             super.run(); | ||||
|             Scanner scanner; | ||||
|             scanner = new Scanner(System.in); | ||||
|             while (scanner.hasNextLine()) { | ||||
|                 String input = scanner.nextLine(); | ||||
|                 //System.out.println(String.format("User Input : %s", input)); | ||||
|  | ||||
| 				_SocketServer.sendMessage(input); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										35
									
								
								libjc/src/main/java/cc/winboll/studio/libjc/TestClassA.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								libjc/src/main/java/cc/winboll/studio/libjc/TestClassA.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| package cc.winboll.studio.libjc; | ||||
|  | ||||
| /** | ||||
|  * @Author ZhanGSKen@QQ.COM | ||||
|  * @Date 2025/01/06 11:14:19 | ||||
|  * @Describe 测试类A | ||||
|  */ | ||||
| public class TestClassA { | ||||
|      | ||||
|     public static final String TAG = "TestClassA"; | ||||
|      | ||||
|     // | ||||
|     // 当前类入口 | ||||
|     //  | ||||
|     // @args[0] 为 "UnitTest" 时就进行单元测试输出 | ||||
|     // | ||||
|     public static void main(String[] args) { | ||||
|         if (args.length == 1 && args[0].equals("UnitTest")) { | ||||
|             //System.out.println("main : "); | ||||
|             System.out.println("args[0] " + args[0]); | ||||
|             //System.out.println("args[1]" + args[1]); | ||||
|             System.out.println(hello(args[0])); | ||||
|         } else { | ||||
|             System.out.println(hello()); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     public static String hello() { | ||||
|         return String.format("Hello, World! %s works well.", TAG); | ||||
|     } | ||||
|  | ||||
|     public static String hello(String name) { | ||||
|         return String.format("Hello, %s! %s works well.", name, TAG); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										37
									
								
								libjc/src/main/java/cc/winboll/studio/libjc/TestClassB.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								libjc/src/main/java/cc/winboll/studio/libjc/TestClassB.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| package cc.winboll.studio.libjc; | ||||
|  | ||||
| /** | ||||
|  * @Author ZhanGSKen@QQ.COM | ||||
|  * @Date 2025/01/09 08:49:08 | ||||
|  * @Describe 测试类B | ||||
|  */ | ||||
| public class TestClassB { | ||||
|      | ||||
|     public static final String TAG = "TestClassB"; | ||||
|      | ||||
|  | ||||
|     // | ||||
|     // 当前类入口 | ||||
|     //  | ||||
|     // @args[0] 为 "UnitTest" 时就进行单元测试输出 | ||||
|     // | ||||
|     public static void main(String[] args) { | ||||
|         if (args.length == 1 && args[0].equals("UnitTest")) { | ||||
|             //System.out.println("main : "); | ||||
|             System.out.println("args[0] " + args[0]); | ||||
|             //System.out.println("args[1]" + args[1]); | ||||
|             System.out.println(hello(args[0])); | ||||
|         } else { | ||||
|             System.out.println(hello()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static String hello() { | ||||
|         return String.format("Hello, World! %s works well.", TAG); | ||||
|     } | ||||
|  | ||||
|     public static String hello(String name) { | ||||
|         return String.format("Hello, %s! %s works well.", name, TAG); | ||||
|     } | ||||
|      | ||||
| } | ||||
							
								
								
									
										278
									
								
								libjc/src/main/java/cc/winboll/studio/libjc/bean/BaseBean.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										278
									
								
								libjc/src/main/java/cc/winboll/studio/libjc/bean/BaseBean.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,278 @@ | ||||
| package main.java.cc.winboll.studio.libjc.bean; | ||||
|  | ||||
| /** | ||||
|  * @Author ZhanGSKen@QQ.COM | ||||
|  * @Date 2024/08/23 15:40:30 | ||||
|  * @Describe Json Bean 基础类。 | ||||
|  */ | ||||
| import android.content.Context; | ||||
| import android.util.JsonReader; | ||||
| import android.util.JsonWriter; | ||||
| import cc.winboll.studio.libjc.util.FileUtils; | ||||
| import cc.winboll.studio.libjc.util.LogUtils; | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.io.StringReader; | ||||
| import java.io.StringWriter; | ||||
| import java.util.ArrayList; | ||||
|  | ||||
| public abstract class BaseBean<T extends BaseBean> { | ||||
|  | ||||
|     public static final String TAG = "BaseBean"; | ||||
|     static final String BEAN_NAME = "BeanName"; | ||||
|  | ||||
|     public BaseBean() {} | ||||
|  | ||||
|     public abstract String getName(); | ||||
|  | ||||
|     public String getBeanJsonFilePath(Context context) { | ||||
|  | ||||
|         return context.getExternalFilesDir(TAG) + "/" + getName() + ".json"; | ||||
|     } | ||||
|  | ||||
|     public String getBeanListJsonFilePath(Context context) { | ||||
|  | ||||
|         return context.getExternalFilesDir(TAG) + "/" + getName() + "_List.json"; | ||||
|     } | ||||
|  | ||||
|     public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException { | ||||
|         jsonWriter.name(BEAN_NAME).value(getName()); | ||||
|     } | ||||
|  | ||||
|     public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     abstract public T readBeanFromJsonReader(JsonReader jsonReader) throws IOException; | ||||
|  | ||||
|     public static <T extends BaseBean> String checkIsTheSameBeanListAndFile(String szFilePath, Class<T> clazz) { | ||||
|         StringBuilder sbResult = new StringBuilder(); | ||||
|         String szErrorInfo = "Check Is The Same Bean List And File Error : "; | ||||
|  | ||||
|         try { | ||||
|             int nSameCount = 0; | ||||
|             int nBeanListCout = 0; | ||||
|  | ||||
|             T beanTemp = clazz.newInstance(); | ||||
|             String szBeanSimpleName = beanTemp.getName(); | ||||
|             String szListJson = FileUtils.readStringFromFile(szFilePath); | ||||
|             StringReader stringReader = new StringReader(szListJson); | ||||
|             JsonReader jsonReader = new JsonReader(stringReader); | ||||
|             jsonReader.beginArray(); | ||||
|             while (jsonReader.hasNext()) { | ||||
|                 nBeanListCout++; | ||||
|                 jsonReader.beginObject(); | ||||
|                 while (jsonReader.hasNext()) { | ||||
|                     String name = jsonReader.nextName(); | ||||
|                     if (name.equals(BEAN_NAME)) { | ||||
|                         if (szBeanSimpleName.equals(jsonReader.nextString())) { | ||||
|                             nSameCount++; | ||||
|                         } | ||||
|                     } else { | ||||
|                         jsonReader.skipValue(); | ||||
|                     } | ||||
|                 } | ||||
|                 jsonReader.endObject(); | ||||
|             } | ||||
|             jsonReader.endArray(); | ||||
|  | ||||
|             // 返回检查结果 | ||||
|             if (nSameCount == nBeanListCout) { | ||||
|                 // 检查一致直接返回空串 | ||||
|                 return ""; | ||||
|             } else { | ||||
|                 // 检查不一致返回对比信息 | ||||
|                 sbResult.append("Total : "); | ||||
|                 sbResult.append(nBeanListCout); | ||||
|                 sbResult.append(" Diff : "); | ||||
|                 sbResult.append(nBeanListCout - nSameCount); | ||||
|             } | ||||
|         } catch (InstantiationException | IllegalAccessException | IOException e) { | ||||
|             sbResult.append(szErrorInfo); | ||||
|             sbResult.append(e); | ||||
|             System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
|             LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|         } | ||||
|         return sbResult.toString(); | ||||
|     } | ||||
|  | ||||
|     public static <T extends BaseBean> T parseStringToBean(String szBean, Class<T> clazz) throws IOException { | ||||
|         // 创建 JsonWriter 对象 | ||||
|         StringReader stringReader = new StringReader(szBean); | ||||
|         JsonReader jsonReader = new JsonReader(stringReader); | ||||
|         try { | ||||
|             T beanTemp = clazz.newInstance(); | ||||
|             return (T)beanTemp.readBeanFromJsonReader(jsonReader); | ||||
|         } catch (InstantiationException | IllegalAccessException | IOException e) { | ||||
|             System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
|             LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public static <T extends BaseBean> boolean parseStringToBeanList(String szBeanList, ArrayList<T> beanList, Class<T> clazz) { | ||||
|         try { | ||||
|             beanList.clear(); | ||||
|             StringReader stringReader = new StringReader(szBeanList); | ||||
|             JsonReader jsonReader = new JsonReader(stringReader); | ||||
|             jsonReader.beginArray(); | ||||
|             while (jsonReader.hasNext()) { | ||||
|                 T beanTemp = clazz.newInstance(); | ||||
|                 T bean = (T)beanTemp.readBeanFromJsonReader(jsonReader); | ||||
|                 if (bean != null) { | ||||
|                     beanList.add(bean); | ||||
|                     //Log.d(TAG, "beanList.add(bean)"); | ||||
|                 } | ||||
|             } | ||||
|             jsonReader.endArray(); | ||||
|             return true; | ||||
|             //Log.d(TAG, "beanList.size() is " + Integer.toString(beanList.size())); | ||||
|         } catch (InstantiationException | IllegalAccessException | IOException e) { | ||||
|             System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
|             LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String toString() { | ||||
|         // 创建 JsonWriter 对象 | ||||
|         StringWriter stringWriter = new StringWriter(); | ||||
|         JsonWriter jsonWriter = new JsonWriter(stringWriter); | ||||
|         jsonWriter.setIndent("  "); | ||||
|         try {// 开始 JSON 对象 | ||||
|             jsonWriter.beginObject(); | ||||
|             // 写入键值对 | ||||
|             writeThisToJsonWriter(jsonWriter); | ||||
|             // 结束 JSON 对象 | ||||
|             jsonWriter.endObject(); | ||||
|             return stringWriter.toString(); | ||||
|         } catch (IOException e) { | ||||
|             System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
|             LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|         } | ||||
|         // 获取 JSON 字符串 | ||||
|         return ""; | ||||
|     } | ||||
|  | ||||
|     public static <T extends BaseBean> String toStringByBeanList(ArrayList<T> beanList) { | ||||
|         try { | ||||
|             StringWriter stringWriter = new StringWriter(); | ||||
|             JsonWriter jsonWriter = new JsonWriter(stringWriter); | ||||
|             jsonWriter.setIndent("  "); | ||||
|             jsonWriter.beginArray(); | ||||
|             for (int i = 0; i < beanList.size(); i++) { | ||||
|                 // 开始 JSON 对象 | ||||
|                 jsonWriter.beginObject(); | ||||
|                 // 写入键值对 | ||||
|                 beanList.get(i).writeThisToJsonWriter(jsonWriter); | ||||
|                 // 结束 JSON 对象 | ||||
|                 jsonWriter.endObject(); | ||||
|             } | ||||
|             jsonWriter.endArray(); | ||||
|             jsonWriter.close(); | ||||
|             return stringWriter.toString(); | ||||
|         } catch (IOException e) { | ||||
|             System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
|             LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|         } | ||||
|         return ""; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public static <T extends BaseBean> T loadBean(Context context, Class<T> clazz) { | ||||
|         try { | ||||
|             T beanTemp = clazz.newInstance(); | ||||
|             return loadBeanFromFile(beanTemp.getBeanJsonFilePath(context), clazz); | ||||
|         } catch (InstantiationException | IllegalAccessException e) { | ||||
|             System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
|             LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public static <T extends BaseBean> T loadBeanFromFile(String szFilePath, Class<T> clazz) { | ||||
|         try { | ||||
|             try { | ||||
|                 File fTemp = new File(szFilePath); | ||||
|                 if (fTemp.exists()) { | ||||
|                     T beanTemp = clazz.newInstance();String szJson = FileUtils.readStringFromFile(szFilePath); | ||||
|                     return beanTemp.parseStringToBean(szJson, clazz); | ||||
|                 } | ||||
|             } catch (InstantiationException | IllegalAccessException e) { | ||||
|                 System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
|                 LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|             } | ||||
|  | ||||
|         } catch (IOException e) { | ||||
|             System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
|             LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public static <T extends BaseBean> boolean saveBean(Context context, T bean) { | ||||
|         return saveBeanToFile(bean.getBeanJsonFilePath(context), bean); | ||||
|     } | ||||
|  | ||||
|     public static <T extends BaseBean> boolean saveBeanToFile(String szFilePath, T bean) { | ||||
|         try { | ||||
|             String szJson = bean.toString(); | ||||
|             FileUtils.writeStringToFile(szFilePath, szJson); | ||||
|             return true; | ||||
|         } catch (IOException e) { | ||||
|             System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
|             LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     public static <T extends BaseBean> boolean loadBeanList(Context context, ArrayList<T> beanListDst, Class<T> clazz) { | ||||
|         try { | ||||
|             T beanTemp = clazz.newInstance(); | ||||
|             return loadBeanListFromFile(beanTemp.getBeanListJsonFilePath(context), beanListDst, clazz); | ||||
|         } catch (InstantiationException | IllegalAccessException e) { | ||||
|             System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
|             LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     public static <T extends BaseBean> boolean loadBeanListFromFile(String szFilePath, ArrayList<T> beanList, Class<T> clazz) { | ||||
|         try { | ||||
|             File fTemp = new File(szFilePath); | ||||
|             if (fTemp.exists()) { | ||||
|                 String szListJson = FileUtils.readStringFromFile(szFilePath); | ||||
|                 return parseStringToBeanList(szListJson, beanList, clazz); | ||||
|             } | ||||
|         } catch (IOException e) { | ||||
|             System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
|             LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     public static <T extends BaseBean> boolean saveBeanList(Context context, ArrayList<T> beanList, Class<T> clazz) { | ||||
|         try { | ||||
|             T beanTemp = clazz.newInstance(); | ||||
|             return saveBeanListToFile(beanTemp.getBeanListJsonFilePath(context), beanList); | ||||
|         } catch (InstantiationException | IllegalAccessException e) { | ||||
|             System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
|             LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     public static <T extends BaseBean> boolean saveBeanListToFile(String szFilePath, ArrayList<T> beanList) { | ||||
|         try { | ||||
|             String szJson = toStringByBeanList(beanList); | ||||
|             FileUtils.writeStringToFile(szFilePath, szJson); | ||||
|             //Log.d(TAG, "FileUtil.writeFile beanList.size() is " + Integer.toString(beanList.size())); | ||||
|             return true; | ||||
|         } catch (IOException e) { | ||||
|             System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
|             LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,75 @@ | ||||
| package cc.winboll.studio.libjc.cmd; | ||||
|  | ||||
| /** | ||||
|  * @Author ZhanGSKen@QQ.COM | ||||
|  * @Date 2025/01/11 12:43:29 | ||||
|  * @Describe 列举定义了main函数的所有类。 | ||||
|  */ | ||||
| import java.io.File; | ||||
| import java.lang.reflect.Method; | ||||
| import java.util.jar.JarEntry; | ||||
| import java.util.jar.JarFile; | ||||
|  | ||||
| public class ListJarClassHasMain { | ||||
|  | ||||
|     public static final String TAG = "ListJarClassHasMain"; | ||||
|  | ||||
|     public static void main(String[] args) { | ||||
|         System.out.println("ListJarClassHasMain main"); | ||||
|         try { | ||||
|             String jarFileName = getCurrentClassJarFileName(); | ||||
|             System.out.println(String.format("\nCurrent Class Jar File Name : %s", jarFileName)); | ||||
|              | ||||
|             File fJarFolder = new File("/sdcard/WinBollStudio/DEV/jars/"); | ||||
|             System.out.println(String.format("\nJars Folder : %s", fJarFolder.getPath())); | ||||
|             for (File fJarFile : fJarFolder.listFiles()) { | ||||
|                 if (fJarFile.getName().endsWith(".jar")) { | ||||
|                     System.out.println(String.format("\nJar File Name : %s", fJarFile.getName())); | ||||
|                     listJarFileMainClass(new JarFile(fJarFile.getPath())); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|         } catch (Exception e) { | ||||
|             System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     static void listJarFileMainClass(JarFile jarFile) { | ||||
|         System.out.println("\nMain Functions Class : "); | ||||
|         //JarFile jarFile = new JarFile("yourJarFile.jar"); | ||||
|         java.util.Enumeration<JarEntry> entries = jarFile.entries(); | ||||
|         while (entries.hasMoreElements()) { | ||||
|             JarEntry entry = entries.nextElement(); | ||||
|             if (entry.getName().endsWith(".class")) { | ||||
|                 String className = entry.getName().replace('/', '.').substring(0, entry.getName().length() - 6); | ||||
|                 try { | ||||
|                     Class<?> clazz = Class.forName(className); | ||||
|                     Method method = clazz.getMethod("main", String[].class); | ||||
|                     if (method != null) { | ||||
|                         System.out.println(className); | ||||
|                     } | ||||
|                 } catch (Exception e) { | ||||
|                     // 没有main方法或者加载类出错,忽略 | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|     public static String getCurrentClassJarFileName() { | ||||
|         String jarFileName = ""; | ||||
|         try { | ||||
|             String classPath = ListJarClassHasMain.class.getProtectionDomain().getCodeSource().getLocation().getPath(); | ||||
|             jarFileName = new java.io.File(classPath).getName(); | ||||
|         } catch (NullPointerException e) { | ||||
|             // 忽略读取Jar文件失败问题,返回空数据 | ||||
|             return ""; | ||||
|         } catch (Exception e) { | ||||
|             System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
|         } | ||||
|         return jarFileName; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -0,0 +1,196 @@ | ||||
| package cc.winboll.studio.libjc.net; | ||||
|  | ||||
| import cc.winboll.studio.libjc.JCMainThread; | ||||
| import cc.winboll.studio.libjc.util.LogUtils; | ||||
| import java.io.IOException; | ||||
| import java.io.PrintWriter; | ||||
| import java.net.Socket; | ||||
| import java.util.Scanner; | ||||
| import cc.winboll.studio.libjc.Main; | ||||
|  | ||||
| public class JCSocketClient { | ||||
|  | ||||
| 	public final static String TAG = "JCSocketClient"; | ||||
|  | ||||
|     public final static String DEFAULT_SERVER = "127.0.0.1"; | ||||
|  | ||||
| 	volatile static JCSocketClient _JCSocketClient; | ||||
|     String mszServer = ""; | ||||
| 	Socket socket; | ||||
| 	Scanner in_socket; | ||||
| 	PrintWriter out_socket; | ||||
| 	Scanner userInput; | ||||
| 	public volatile boolean isMessage2Server; | ||||
| 	public volatile String szMessage2Server; | ||||
|     ClientMessageSendThread mClientMessageSendThread; | ||||
|     //SyncMesaageThread mSyncMesaageThread; | ||||
|     ConsoleMessageSendThread mConsoleMessageSendThread; | ||||
|  | ||||
| 	JCSocketClient() { | ||||
|         LogUtils.d(TAG, "JCSocketClient()"); | ||||
|         isMessage2Server = false; | ||||
|         szMessage2Server = ""; | ||||
| 	} | ||||
|  | ||||
| 	public static JCSocketClient getInstance() { | ||||
| 		if (_JCSocketClient == null) { | ||||
| 			_JCSocketClient = new JCSocketClient(); | ||||
| 		} | ||||
| 		return _JCSocketClient; | ||||
| 	} | ||||
|  | ||||
|     public static void main(String[] args) { | ||||
|         System.out.println("JCSocketClient main :"); | ||||
|          | ||||
|         JCSocketClient jcSocketClient = JCSocketClient.getInstance(); | ||||
|         if (args != null && args.length == 1 && !args.equals("")) { | ||||
|             jcSocketClient.mszServer = args[0]; | ||||
|         } else { | ||||
|             jcSocketClient.mszServer = DEFAULT_SERVER; | ||||
|         } | ||||
| 		jcSocketClient.start(); | ||||
| 	} | ||||
|      | ||||
|     public void start(String server) { | ||||
|         mszServer = server; | ||||
|         start(); | ||||
|     } | ||||
|  | ||||
|     void start() { | ||||
|         System.out.println("JCSocketClient start()"); | ||||
|         // 连接服务器 | ||||
|         try { | ||||
|             System.out.println(String.format("Connect to %s", mszServer)); | ||||
|             socket = new Socket(mszServer, 8888); | ||||
|             System.out.println("已连接到服务器"); | ||||
|             // 获取输出流 | ||||
|             out_socket = new PrintWriter(socket.getOutputStream(), true); | ||||
|             // 获取输入流 | ||||
|             in_socket = new Scanner(socket.getInputStream()); | ||||
|             //userInput = new Scanner(System.in); | ||||
|  | ||||
|             mClientMessageSendThread = new ClientMessageSendThread(); | ||||
|             mClientMessageSendThread.start(); | ||||
| //            mSyncMesaageThread = new SyncMesaageThread(); | ||||
| //            mSyncMesaageThread.start(); | ||||
|             if (Main.getRunningMode() == Main.JAR_RUNNING_MODE.CONSOLE | ||||
|                 || Main.getRunningMode() == Main.JAR_RUNNING_MODE.JC) { | ||||
|                 mConsoleMessageSendThread = new ConsoleMessageSendThread(); | ||||
|                 mConsoleMessageSendThread.start(); | ||||
|             } | ||||
|             // 开始发送消息 | ||||
|             //sendMessage(String.format("%s OK", TAG)); | ||||
|  | ||||
|         } catch (IOException e) { | ||||
|             System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
|             LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|         } | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	public void sendMessage(String message) { | ||||
|         //Log.d(TAG, String.format("sendMessage : %s", message)); | ||||
| 		szMessage2Server = message; | ||||
| 		isMessage2Server = true; | ||||
| 	} | ||||
|  | ||||
| //    public synchronized void syncClientMessage() { | ||||
| //        //Log.d(TAG, "syncClientMessage()"); | ||||
| //        //System.out.println("syncClientMessage()"); | ||||
| //        if (isClientMessageReady) { | ||||
| //            isClientMessageReady = false; | ||||
| //            //System.out.println(String.format("Client : %s", szClientMessage)); | ||||
| //            //Log.d(TAG, String.format("Send %s", szClientMessage)); | ||||
| //            //out_socket.println(szClientMessage); | ||||
| //            out_socket.println(szClientMessage); | ||||
| //            System.out.println(String.format("out_socket->%s", szClientMessage)); | ||||
| //            szClientMessage = ""; | ||||
| //        } | ||||
| //	} | ||||
|  | ||||
|     public synchronized void scan_in_socket() { | ||||
|         //Log.d(TAG, "scan_in_socket()"); | ||||
|         //System.out.println("scan_in_socket"); | ||||
|  | ||||
|         if (in_socket.hasNextLine()) { | ||||
|             //Log.d(TAG, "Reciving System Input Message..."); | ||||
|             String response = in_socket.nextLine(); | ||||
|             System.out.println(String.format("%s :%s", JCSocketServer.TAG, response)); | ||||
|         } | ||||
| 	} | ||||
|  | ||||
| 	class ClientMessageSendThread extends Thread { | ||||
|  | ||||
| 		@Override | ||||
| 		public void run() { | ||||
| 			super.run(); | ||||
|             try { | ||||
|                 // 向服务器发送消息 | ||||
|                 while (true) { | ||||
|                     if (isMessage2Server) { | ||||
|                         isMessage2Server = false; | ||||
|                         //System.out.println(String.format("Client : %s", szClientMessage)); | ||||
|                         //Log.d(TAG, String.format("Send %s", szClientMessage)); | ||||
|                         //out_socket.println(szClientMessage); | ||||
|                         out_socket.println(szMessage2Server); | ||||
|                         System.out.println(String.format("%s : %s", TAG, szMessage2Server)); | ||||
|                         szMessage2Server = ""; | ||||
|                     } | ||||
| //                    syncClientMessage(); | ||||
| //                    try { | ||||
| //                        //syncClientMessage(); | ||||
| //                        Thread.sleep(1000); | ||||
| //                    } catch (InterruptedException e) { | ||||
| //                        Log.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
| //                    } | ||||
|                 } | ||||
|             } catch (Exception e) { | ||||
|                 System.err.println(String.format("%s ClientMessageSendThread : %s", TAG, e.getMessage())); | ||||
|                 LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|             } | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
|  | ||||
| //    class SyncMesaageThread extends Thread { | ||||
| // | ||||
| //        @Override | ||||
| //        public void run() { | ||||
| //            super.run(); | ||||
| //            while (true) { | ||||
| //                sendMessage(String.format("%s OK", TAG)); | ||||
| //                try { | ||||
| //                    Thread.sleep(5000); | ||||
| //                } catch (InterruptedException e) { | ||||
| //                    System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
| //                    Log.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
| //                } | ||||
| //            } | ||||
| //        } | ||||
| //    } | ||||
|  | ||||
|     class ConsoleMessageSendThread extends Thread { | ||||
|  | ||||
|         @Override | ||||
|         public void run() { | ||||
|             super.run(); | ||||
|             try { | ||||
|                 System.out.println("ConsoleMessageSendThread run()"); | ||||
|  | ||||
|                 // 读取服务器响应 | ||||
|                 while (true) { | ||||
|                     scan_in_socket(); | ||||
| //                    try { | ||||
| //                        syncSystemInMessage(); | ||||
| //                        Thread.sleep(3000); | ||||
| //                    } catch (InterruptedException e) { | ||||
| //                        Log.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
| //                    } | ||||
|                 } | ||||
|             } catch (Exception e) { | ||||
|                 System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
|                 LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|             } | ||||
|         } | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,204 @@ | ||||
| package cc.winboll.studio.libjc.net; | ||||
|  | ||||
| import cc.winboll.studio.libjc.JCMainThread; | ||||
| import cc.winboll.studio.libjc.Main; | ||||
| import cc.winboll.studio.libjc.util.ConsoleUtils; | ||||
| import cc.winboll.studio.libjc.util.LogUtils; | ||||
| import java.io.IOException; | ||||
| import java.io.PrintWriter; | ||||
| import java.net.ServerSocket; | ||||
| import java.net.Socket; | ||||
| import java.util.Scanner; | ||||
|  | ||||
| public class JCSocketServer { | ||||
|  | ||||
| 	public final static String TAG = "JCSocketServer"; | ||||
|  | ||||
| 	volatile static JCSocketServer _JCSocketServer; | ||||
| 	ServerSocket serverSocket; | ||||
| 	Socket clientSocket; | ||||
| 	Scanner in_socket; | ||||
| 	PrintWriter out_socket; | ||||
| 	public volatile boolean isServerMessageReady; | ||||
| 	public volatile String szServerMessage; | ||||
|     ServerMessageSendThread mServerMessageSendThread; | ||||
|     //SyncMesaageThread mSyncMesaageThread; | ||||
|     ConsoleMessageSendThread mConsoleMessageSendThread; | ||||
|  | ||||
|  | ||||
| 	JCSocketServer() { | ||||
| 		ConsoleUtils.Debug.printFuncInfo(TAG); | ||||
|         //Log.d(TAG, "JCSocketClient()"); | ||||
|         isServerMessageReady = false; | ||||
|         szServerMessage = ""; | ||||
| 	} | ||||
|  | ||||
| 	public static JCSocketServer getInstance() { | ||||
| 		if (_JCSocketServer == null) { | ||||
| 			_JCSocketServer = new JCSocketServer(); | ||||
| 		} | ||||
| 		return _JCSocketServer; | ||||
| 	} | ||||
|  | ||||
|     public static void main(String[] args) { | ||||
|         System.out.println("JCSocketServer main :"); | ||||
| 		JCSocketServer.getInstance().start(); | ||||
| 	} | ||||
|  | ||||
|  | ||||
|  | ||||
| 	void start() { | ||||
|         System.out.println("JCSocketServer start :"); | ||||
|         // 连接服务器 | ||||
|         try { | ||||
| 			// 创建一个ServerSocket,监听端口8888 | ||||
|             serverSocket = new ServerSocket(8888); | ||||
|             System.out.println("服务器已启动,等待客户端连接..."); | ||||
|             // 等待客户端连接 | ||||
|             clientSocket = serverSocket.accept(); | ||||
|             LogUtils.d(TAG, "客户端已连接"); | ||||
|             System.out.println("客户端已连接"); | ||||
|             out_socket = new PrintWriter(clientSocket.getOutputStream(), true); | ||||
|             in_socket = new Scanner(clientSocket.getInputStream()); | ||||
| 			 | ||||
|  | ||||
|             mServerMessageSendThread = new ServerMessageSendThread(); | ||||
|             mServerMessageSendThread.start(); | ||||
| //            mSyncMesaageThread = new SyncMesaageThread(); | ||||
| //            mSyncMesaageThread.start(); | ||||
|             if (Main.getRunningMode() == Main.JAR_RUNNING_MODE.CONSOLE | ||||
| 				|| Main.getRunningMode() == Main.JAR_RUNNING_MODE.JCNDK) { | ||||
|                 mConsoleMessageSendThread = new ConsoleMessageSendThread(); | ||||
|                 mConsoleMessageSendThread.start(); | ||||
|             } | ||||
|             System.out.println("JCSocketServer start() end."); | ||||
|  | ||||
|         } catch (IOException e) { | ||||
|             System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
|             LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|         } | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	public void sendMessage(String message) { | ||||
|         //Log.d(TAG, String.format("sendMessage : %s", message)); | ||||
| 		szServerMessage = message; | ||||
| 		isServerMessageReady = true; | ||||
| 	} | ||||
|  | ||||
| //    public synchronized void syncServerMessage() { | ||||
| //        //Log.d(TAG, "syncServerMessage()"); | ||||
| //        //System.out.println("syncServerMessage()"); | ||||
| ////        if (isServerMessageReady) { | ||||
| ////            isServerMessageReady = false; | ||||
| ////            //System.out.println(String.format("JCSocketServer : %s", szServerMessage)); | ||||
| ////            //Log.d(TAG, String.format("Send %s", szClientMessage)); | ||||
| ////            out.println(szServerMessage); | ||||
| ////            szServerMessage = ""; | ||||
| ////        } | ||||
| //	} | ||||
|  | ||||
| //    public synchronized void syncSystemInMessage() { | ||||
| //        //Log.d(TAG, "syncSystemInMessage()"); | ||||
| //        //System.out.println("syncSystemInMessage"); | ||||
| // | ||||
| //        if (in_socket.hasNextLine()) { | ||||
| //            //Log.d(TAG, "Reciving System Input Message..."); | ||||
| //            String response = in_socket.nextLine(); | ||||
| //            System.out.println("Recived :" + response); | ||||
| //             | ||||
| //            // 发送一个消息回去给客户端 | ||||
| //            out_socket.println(String.format("%s : Recived [%s]", TAG, response)); | ||||
| //        } | ||||
| //	} | ||||
|  | ||||
| 	class ServerMessageSendThread extends Thread { | ||||
|  | ||||
| 		@Override | ||||
| 		public void run() { | ||||
| 			super.run();// 获取输入输出流 | ||||
|             try { | ||||
|                 // 向客户端发送消息 | ||||
|                 while (true) { | ||||
| 					 | ||||
| //					if(userInput.hasNextLine()) { | ||||
| //						String szServerMessage = userInput.nextLine(); | ||||
| //						System.out.println(String.format("Send [%s] to client.", szServerMessage)); | ||||
| //						out_socket.println(szServerMessage); | ||||
| //					} | ||||
|                     if (isServerMessageReady) { | ||||
|                         isServerMessageReady = false; | ||||
|                         //System.out.println(String.format("JCSocketServer : %s", szServerMessage)); | ||||
|                         //Log.d(TAG, String.format("Send %s", szClientMessage)); | ||||
| 						System.out.println(String.format("%s : %s", TAG, szServerMessage)); | ||||
|                         out_socket.println(szServerMessage); | ||||
|                         szServerMessage = ""; | ||||
|                     } | ||||
|                     //syncServerMessage(); | ||||
| //                    try { | ||||
| //                        syncServerMessage(); | ||||
| //                        Thread.sleep(500); | ||||
| //                    } catch (Exception e) { | ||||
| //                        System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
| //                        Log.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
| //                    } | ||||
|                 } | ||||
|             } catch (Exception e) { | ||||
|                 System.err.println(String.format("%s ServerMessageSendThread : %s", TAG, e.getMessage())); | ||||
|                 LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|             } | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
|  | ||||
| //    class SyncMesaageThread extends Thread { | ||||
| // | ||||
| //        @Override | ||||
| //        public void run() { | ||||
| //            super.run(); | ||||
| //            while (true) { | ||||
| //                sendMessage(String.format("%s OK", TAG)); | ||||
| //                try { | ||||
| //                    Thread.sleep(5000); | ||||
| //                } catch (InterruptedException e) { | ||||
| //                    System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
| //                    Log.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
| //                } | ||||
| //            } | ||||
| //        } | ||||
| //    } | ||||
|  | ||||
|     class ConsoleMessageSendThread extends Thread { | ||||
|  | ||||
|         @Override | ||||
|         public void run() { | ||||
|             super.run(); | ||||
|             // 获取输入输出流 | ||||
|             try { | ||||
|                 System.out.println("ConsoleMessageSendThread run()"); | ||||
| 				 | ||||
|                 // 读取服务器响应 | ||||
|                 while (true) { | ||||
|                     if (in_socket.hasNextLine()) { | ||||
|                         //Log.d(TAG, "Reciving System Input Message..."); | ||||
|                         String response = in_socket.nextLine(); | ||||
|                         System.out.println(String.format("%s :%s", JCSocketClient.TAG, response)); | ||||
|  | ||||
|                         // 发送一个消息回去给客户端 | ||||
|                         //out_socket.println(String.format("%s : Recived [%s]", TAG, response)); | ||||
|                     } | ||||
|                     //syncSystemInMessage(); | ||||
| //                    try { | ||||
| //                        //syncSystemInMessage(); | ||||
| //                        Thread.sleep(1000); | ||||
| //                    } catch (InterruptedException e) { | ||||
| //                        Log.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
| //                    } | ||||
|                 } | ||||
| 			} catch (Exception e) { | ||||
|                 System.err.println(String.format("%s ConsoleMessageSendThread : %s", TAG, e.getMessage())); | ||||
| 				LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
| 			} | ||||
|         } | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,88 @@ | ||||
| package cc.winboll.studio.libjc.net; | ||||
| import android.util.JsonReader; | ||||
| import android.util.JsonWriter; | ||||
| import java.io.IOException; | ||||
| import main.java.cc.winboll.studio.libjc.bean.BaseBean; | ||||
|  | ||||
| /** | ||||
|  * @Author ZhanGSKen@QQ.COM | ||||
|  * @Date 2025/01/09 20:07:06 | ||||
|  * @Describe 消息类 | ||||
|  */ | ||||
| public class MesaageBean extends BaseBean { | ||||
|  | ||||
|     public static final String TAG = "MesaageBean"; | ||||
|  | ||||
|     public static enum MESAAGE_TYPE { | ||||
|         UNKNOWN, | ||||
|         CONNECTION_STATUS, | ||||
|         MESSAGE | ||||
|         ; | ||||
|     } | ||||
|  | ||||
|     MESAAGE_TYPE mMESAAGE_TYPE = MESAAGE_TYPE.UNKNOWN; | ||||
|     String messageContents; | ||||
|  | ||||
|  | ||||
|     public void setMESAAGE_TYPE(MESAAGE_TYPE type) { | ||||
|         this.mMESAAGE_TYPE = type; | ||||
|     } | ||||
|  | ||||
|     public MESAAGE_TYPE getMESAAGE_TYPE() { | ||||
|         return mMESAAGE_TYPE; | ||||
|     } | ||||
|  | ||||
|     public void setMessageContents(String messageContents) { | ||||
|         this.messageContents = messageContents; | ||||
|     } | ||||
|  | ||||
|     public String getMessageContents() { | ||||
|         return messageContents; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String getName() { | ||||
|         return MesaageBean.class.getName(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException { | ||||
|         super.writeThisToJsonWriter(jsonWriter); | ||||
|         MesaageBean bean = this; | ||||
|         jsonWriter.name("MESAAGE_TYPE").value(bean.mMESAAGE_TYPE.ordinal()); | ||||
|         jsonWriter.name("messageContents").value(bean.getMessageContents()); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException { | ||||
|         if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else { | ||||
|             if (name.equals("MESAAGE_TYPE")) { | ||||
|                 setMESAAGE_TYPE(MESAAGE_TYPE.values()[jsonReader.nextInt()]); | ||||
|             } else if (name.equals("messageContents")) { | ||||
|                 setMessageContents(jsonReader.nextString()); | ||||
|             } else { | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public BaseBean readBeanFromJsonReader(JsonReader jsonReader) throws IOException { | ||||
|         jsonReader.beginObject(); | ||||
|         while (jsonReader.hasNext()) { | ||||
|             String name = jsonReader.nextName(); | ||||
|             if (!initObjectsFromJsonReader(jsonReader, name)) { | ||||
|                 jsonReader.skipValue(); | ||||
|             } | ||||
|         } | ||||
|         // 结束 JSON 对象 | ||||
|         jsonReader.endObject(); | ||||
|         return this; | ||||
|     } | ||||
|      | ||||
|     public MesaageBean parseString() { | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,5 @@ | ||||
| package main.java.cc.winboll.studio.libjc.task; | ||||
|  | ||||
| public class TermuxUniteTask | ||||
| { | ||||
| } | ||||
| @@ -0,0 +1,36 @@ | ||||
| package cc.winboll.studio.libjc.util; | ||||
|  | ||||
| import cc.winboll.studio.libjc.Main; | ||||
|  | ||||
| public class ConsoleUtils { | ||||
|  | ||||
| 	public static String TAG = "ConsoleUtils"; | ||||
|  | ||||
| 	public static class Debug { | ||||
|  | ||||
|  | ||||
| 		public static void printFuncInfo(String tag) { | ||||
| 			if (Main._DEBUG) { | ||||
| 				String methodName = ""; | ||||
| 				int lineNumber = 0; | ||||
| 				try { | ||||
| 					// 获取当前正在执行的栈帧 | ||||
| 					StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); | ||||
| 					// 一般取第2个元素(索引为1)对应的就是当前调用的方法,可根据实际情况调整 | ||||
| 					methodName = stackTrace[3].getMethodName(); | ||||
| 					lineNumber = stackTrace[3].getLineNumber(); | ||||
| 					System.out.println(String.format("[ Class=>%s ] [ Line=>(%d) ] [ Func=>%s ]: ", tag, lineNumber, methodName)); | ||||
| 				} catch (Exception e) { | ||||
| 					System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
|         public static void printObjectInfo(String objName, Object obj) { | ||||
|             if (Main._DEBUG) { | ||||
|                 System.out.println(String.format("[ %s : %s ]", objName, obj.toString())); | ||||
|             } | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,81 @@ | ||||
| package cc.winboll.studio.libjc.util; | ||||
|  | ||||
| /** | ||||
|  * @Author ZhanGSKen@QQ.COM | ||||
|  * @Date 2024/08/12 13:46:32 | ||||
|  * @Describe 文件处理工具 | ||||
|  */ | ||||
| import java.io.File; | ||||
| import java.io.FileInputStream; | ||||
| import java.io.FileOutputStream; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStreamReader; | ||||
| import java.io.OutputStreamWriter; | ||||
| import java.nio.charset.StandardCharsets; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.Paths; | ||||
|  | ||||
| public class FileUtils { | ||||
|  | ||||
|     public static final String TAG = "FileUtils"; | ||||
|  | ||||
|     // | ||||
|     // 把字符串写入文件,指定 UTF-8 编码 | ||||
|     // | ||||
|     public static void writeStringToFile(String szFilePath, String szContent) throws IOException { | ||||
|         File file = new File(szFilePath); | ||||
|         if (!file.getParentFile().exists()) { | ||||
|             file.getParentFile().mkdirs(); | ||||
|         } | ||||
|         FileOutputStream outputStream = new FileOutputStream(file); | ||||
|         OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8); | ||||
|         writer.write(szContent); | ||||
|         writer.close(); | ||||
|     } | ||||
|  | ||||
|     // | ||||
|     // 读取文件到字符串,指定 UTF-8 编码 | ||||
|     // | ||||
|     public static String readStringFromFile(String szFilePath) throws IOException { | ||||
|         File file = new File(szFilePath); | ||||
|         FileInputStream inputStream = new FileInputStream(file); | ||||
|         InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); | ||||
|         StringBuilder content = new StringBuilder(); | ||||
|         int character; | ||||
|         while ((character = reader.read()) != -1) { | ||||
|             content.append((char) character); | ||||
|         } | ||||
|         reader.close(); | ||||
|         return content.toString(); | ||||
|     } | ||||
|  | ||||
|     public static boolean copyFile(File srcFile, File dstFile) { | ||||
|         if (!srcFile.exists()) { | ||||
|             LogUtils.d(TAG, "The original file does not exist."); | ||||
|         } else { | ||||
|             try { | ||||
|                 // 源文件路径 | ||||
|                 Path sourcePath = Paths.get(srcFile.getPath()); | ||||
|                 // 目标文件路径 | ||||
|                 Path destPath = Paths.get(dstFile.getPath()); | ||||
|                 // 建立目标父级文件夹 | ||||
|                 if (!dstFile.getParentFile().exists()) { | ||||
|                     dstFile.getParentFile().mkdirs(); | ||||
|                 } | ||||
|                 // 删除旧的目标文件 | ||||
|                 if (dstFile.exists()) { | ||||
|                     dstFile.delete(); | ||||
|                 } | ||||
|                 // 拷贝文件 | ||||
|                 Files.copy(sourcePath, destPath); | ||||
|                 LogUtils.d(TAG, "File copy successfully."); | ||||
|                 return true; | ||||
|             } catch (Exception e) { | ||||
|                 System.err.println(String.format("%s Exception : %s", TAG, e.getMessage())); | ||||
|                 LogUtils.e(TAG, e, Thread.currentThread().getStackTrace()); | ||||
|             } | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,93 @@ | ||||
| package cc.winboll.studio.libjc.util; | ||||
|  | ||||
| /** | ||||
|  * @Author ZhanGSKen@QQ.COM | ||||
|  * @Date 2025/01/06 18:47:05 | ||||
|  * @Describe 日志类 | ||||
|  */ | ||||
| import java.io.File; | ||||
| import java.io.FileOutputStream; | ||||
| import java.io.IOException; | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.util.Date; | ||||
|  | ||||
| public class LogUtils { | ||||
|  | ||||
|     public static final String TAG = "Log"; | ||||
|  | ||||
|     static SimpleDateFormat _SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | ||||
|     static File _fLog; | ||||
|     static volatile LogUtils _Log; | ||||
|     static volatile boolean _LogInitOK = false; | ||||
|  | ||||
|     public synchronized static void init(String logName) { | ||||
| 		ConsoleUtils.Debug.printFuncInfo(TAG); | ||||
| 		 | ||||
|         if (_Log == null) { | ||||
|             _LogInitOK = false; | ||||
|             _Log = new LogUtils(); | ||||
|             File fLogDir = new File("/sdcard/WinBollStudio/Logs"); | ||||
|             if (!fLogDir.exists()) { | ||||
|                 System.out.println("Log dir not exist : /sdcard/WinBollStudio/Logs"); | ||||
|                 return; | ||||
|             } | ||||
|             _fLog = new File(fLogDir, ((logName == null || logName.equals("")) ?TAG: logName) + ".txt"); | ||||
|             ConsoleUtils.Debug.printObjectInfo("_LogInitOK", _LogInitOK); | ||||
|             //System.out.println("Log Init OK!"); | ||||
|             _LogInitOK = true; | ||||
|             ConsoleUtils.Debug.printObjectInfo("_LogInitOK", _LogInitOK); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static void d(String tag, String msg) { | ||||
|         if (!_LogInitOK) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             Date date = new Date(); | ||||
|             String formattedDate = _SimpleDateFormat.format(date); | ||||
|             FileOutputStream fos = new FileOutputStream(_fLog, true); | ||||
|             fos.write(String.format("[ %s ]<%s> :\n%s\n", formattedDate, tag, msg).getBytes()); | ||||
|             fos.close(); | ||||
|  | ||||
| //            JCMainThread.OnMessageListener listener = JCMainThread.getOnLogListener(); | ||||
| //            if (listener != null) { | ||||
| //                listener.log(msg); | ||||
| //            } | ||||
|         } catch (IOException e) { | ||||
|             System.err.println(String.format("%s Exception : %s", LogUtils.class.getName(), e.getMessage())); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static void e(String tag, Exception e, StackTraceElement[] listStackTrace) { | ||||
|         if (!_LogInitOK) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             Date date = new Date(); | ||||
|             String formattedDate = _SimpleDateFormat.format(date); | ||||
|             StringBuilder sbMessage = new StringBuilder(String.format("[ %s ]<%s> :\n%s -> \n", formattedDate, tag, e.getClass().getName())); | ||||
|             FileOutputStream fos = new FileOutputStream(_fLog, true); | ||||
|             sbMessage.append("At [ function : "); | ||||
|             sbMessage.append(listStackTrace[2].getMethodName()); | ||||
|             sbMessage.append(" ]( "); | ||||
|             sbMessage.append(listStackTrace[2].getFileName()); | ||||
|             sbMessage.append(" : "); | ||||
|             sbMessage.append(listStackTrace[2].getLineNumber()); | ||||
|             sbMessage.append(" )"); | ||||
|             fos.write(sbMessage.toString().getBytes()); | ||||
|             fos.close(); | ||||
|  | ||||
|             //System.err.println(sbMessage.toString()); | ||||
|  | ||||
| //            JCMainThread.OnMessageListener listener = JCMainThread.getOnLogListener(); | ||||
| //            if (listener != null) { | ||||
| //                listener.log(sbMessage.toString()); | ||||
| //            } | ||||
|         } catch (IOException ex) { | ||||
|             System.err.println(String.format("%s Exception : %s", LogUtils.class.getName(), ex.getMessage())); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										
											BIN
										
									
								
								libjc/src/main/res/drawable-hdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								libjc/src/main/res/drawable-hdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 9.2 KiB | 
							
								
								
									
										
											BIN
										
									
								
								libjc/src/main/res/drawable-mdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								libjc/src/main/res/drawable-mdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 5.1 KiB | 
							
								
								
									
										
											BIN
										
									
								
								libjc/src/main/res/drawable-xhdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								libjc/src/main/res/drawable-xhdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 14 KiB | 
							
								
								
									
										
											BIN
										
									
								
								libjc/src/main/res/drawable-xxhdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								libjc/src/main/res/drawable-xxhdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 19 KiB | 
							
								
								
									
										11
									
								
								libjc/src/main/res/layout/library.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								libjc/src/main/res/layout/library.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="match_parent" | ||||
|     android:gravity="center"> | ||||
|  | ||||
|     <TextView | ||||
|         android:text="@string/hello_world" | ||||
|         android:layout_width="wrap_content" | ||||
|         android:layout_height="wrap_content" /> | ||||
|  | ||||
| </LinearLayout> | ||||
							
								
								
									
										5
									
								
								libjc/src/main/res/values-v21/styles.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								libjc/src/main/res/values-v21/styles.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <resources> | ||||
|     <style name="AppTheme" parent="@android:style/Theme.Material.Light"> | ||||
| 	</style> | ||||
| </resources> | ||||
							
								
								
									
										7
									
								
								libjc/src/main/res/values/strings.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								libjc/src/main/res/values/strings.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <resources> | ||||
|  | ||||
|     <string name="lib_name">libjc</string> | ||||
|     <string name="hello_world">Hello world!</string> | ||||
|  | ||||
| </resources> | ||||
							
								
								
									
										5
									
								
								libjc/src/main/res/values/styles.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								libjc/src/main/res/values/styles.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <resources> | ||||
|     <style name="AppTheme" parent="@android:style/Theme.Holo.Light"> | ||||
| 	</style> | ||||
| </resources> | ||||
		Reference in New Issue
	
	Block a user
	 ZhanGSKen
					ZhanGSKen