Some problems encountered and their answers in work (Android Chapter 2)
代码中读取logcat中指定TAG的log信息
方法一:
Process process = Runtime . getRuntime ( ) . exec ( "logcat -d" ) ;
BufferedReader bufferedReader = new BufferedReader (
new InputStreamReader ( process. getInputStream ( ) ) ) ;
StringBuilder log = new StringBuilder ( ) ;
String line = "" ;
while ( ( line = bufferedReader. readLine ( ) ) != null ) {
if ( line. contains ( "MyTag" ) )
{
log. append ( line) ;
}
}
System . out. println ( log) ;
方法二:
public class ReadLogcat {
public static String read ( String tag) {
StringBuilder stringBuilder = new StringBuilder ( ) ;
try {
String [ ] command = { "/system/bin/logcat" , "-d" , "-v" , "time" , tag } ;
Process process = Runtime . getRuntime ( ) . exec ( command) ;
BufferedReader bufferedReader = new BufferedReader (
new InputStreamReader ( process. getInputStream ( ) ) ) ;
stringBuilder. append ( "----------Log start ----------\n" ) ;
String line;
while ( ( line = bufferedReader. readLine ( ) ) != null ) {
stringBuilder. append ( line) . append ( "\n" ) ;
}
stringBuilder. append ( "----------Log end ----------\n" ) ;
bufferedReader. close ( ) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
return stringBuilder. toString ( ) ;
}
public static void main ( String [ ] args) {
String tag= "MyTag" ;
String log = ReadLogcat . read ( tag) ;
System . out. println ( log) ;
}
}
方法三:
public static String getLogcat ( String tag) {
Process process = null ;
BufferedReader bufferedReader = null ;
StringBuilder logcatBuilder = new StringBuilder ( ) ;
try {
process = Runtime . getRuntime ( ) . exec ( "logcat -d" ) ;
bufferedReader = new BufferedReader ( new InputStreamReader ( process. getInputStream ( ) ) ) ;
String line;
while ( ( line = bufferedReader. readLine ( ) ) != null ) {
if ( line. contains ( tag) ) {
logcatBuilder. append ( line) ;
}
}
} catch ( IOException e) {
e. printStackTrace ( ) ;
} finally {
if ( process != null ) {
process. destroy ( ) ;
}
if ( bufferedReader != null ) {
try {
bufferedReader. close ( ) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
}
}
return logcatBuilder. toString ( ) ;
}
String logcat = getLogcat ( "MyTag" ) ;
System . out. println ( logcat) ;
```
MD5加密
import java. security. MessageDigest ;
import java. io. File ;
import java. io. FileInputStream ;
import java. security. NoSuchAlgorithmException ;
public class MD5Example {
public static String getMD5 ( File file) {
MessageDigest digest;
FileInputStream inputStream;
byte [ ] buffer = new byte [ 8192 ] ;
int read;
StringBuilder builder = new StringBuilder ( ) ;
try {
digest = MessageDigest . getInstance ( "MD5" ) ;
inputStream = new FileInputStream ( file) ;
while ( ( read = inputStream. read ( buffer) ) > 0 ) {
digest. update ( buffer, 0 , read) ;
}
byte [ ] md5sum = digest. digest ( ) ;
for ( byte b : md5sum) {
builder. append ( Integer . toString ( ( b & 0xff ) + 0x100 , 16 ) . substring ( 1 ) ) ;
}
return builder. toString ( ) ;
} catch ( Exception ex) {
ex. printStackTrace ( ) ;
return null ;
}
}
}
代码中 getMD5 ( File file) 方法接收一个文件对象并返回文件的 MD5 哈希值。该方法使用 MessageDigest . getInstance ( "MD5" )
获取 MessageDigest 实例,然后使用 FileInputStream 读取文件并更新 MessageDigest 对象。最后,使用 digest. digest ( )
计算哈希值并将其转换为十六进制格式
MD5 算法是一种单向哈希函数,它是不可逆的,所以它不能被解密。通常情况下,MD5 哈希值被用作数据完整性的验证或密码的存储。在验证数据完整性时,计算数据的哈希值并与存储的哈希值进行比较即可判断数据是否被篡改。在存储密码时,将密码的哈希值存储在数据库中,用户登录时计算密码的哈希值并与存储的哈希值进行比较,以验证用户的身份。换句话说,一般情况下,我们并不需要对 MD5 值进行解密,因为这是不可能的。
在Service里面更新UI
在 Service 中更新 UI 通常不是一个好的做法,因为 Service 不应该与 UI 直接交互。Service 主要用于在后台处理长时间运行的任务,而不需要与用户界面进行交互。
如果您的 Service 需要更新 UI,请考虑使用广播(Broadcast)或回调(Callback)机制来通知应用程序的其他部分进行 UI 更新。具体实现步骤如下:
1. 在 Service 中定义一个广播或回调接口,用于通知应用程序的其他部分进行 UI 更新。
2. 在需要更新 UI 的地方,创建一个 BroadcastReceiver(或回调对象),将其注册到 Service 中并设置接收广播的 IntentFilter(或将回调对象作为参数传递给 Service)。
3. 在 Service 中,当后台任务完成并需要更新 UI 时,发送广播或调用回调接口,将需要更新的信息作为 Intent 打包或作为回调参数传递。
4. 在 BroadcastReceiver 或回调对象中,实现相应的代码来更新 UI。
请注意,使用广播或回调来更新 UI 时,应该注意适当的线程安全,例如使用 Handler 或 runOnUiThread() 方法在主线程中更新 UI。
如果您仍然决定在 Service 中直接更新 UI,可以使用以下方法:
1. 在 Service 中获取当前 Activity 的引用。
2. 在 Activity 中定义 public 方法,用于更新 UI。
3. 在 Service 中调用 Activity 中定义的方法,更新 UI。
这种方法需要小心处理潜在的内存泄漏和线程安全性问题,因为 Service 和 Activity 可能在不同的线程和生命周期中运行。
以下是在 Service 中使用广播机制更新 UI 的示例代码:
在 Service 中定义广播接口:
public interface OnUpdateUIListener {
void onUpdateUI ( String message) ;
}
在 Service 中发送广播:
Intent intent = new Intent ( "com.example.myapp.UPDATE_UI" ) ;
intent. putExtra ( "message" , "更新消息" ) ;
sendBroadcast ( intent) ;
在 Activity 中注册广播接收器:
private BroadcastReceiver myReceiver = new BroadcastReceiver ( ) {
@Override
public void onReceive ( Context context, Intent intent) {
String message = intent. getStringExtra ( "message" ) ;
updateUI ( message) ;
}
} ;
@Override
protected void onResume ( ) {
super . onResume ( ) ;
IntentFilter intentFilter = new IntentFilter ( "com.example.myapp.UPDATE_UI" ) ;
registerReceiver ( myReceiver, intentFilter) ;
}
@Override
protected void onPause ( ) {
super . onPause ( ) ;
unregisterReceiver ( myReceiver) ;
}
private void updateUI ( String message) {
}
当 Service 完成任务并需要更新 UI 时,调用发送广播的方法即可。
请注意,前面提到的回调机制也可以类似地使用。在 Service 中定义回调接口,将回调对象传递给 Service ,在需要更新 UI 时调用回调接口即可。在 Activity 中实现回调接口,并在回调方法中更新 UI。
以下是在 Service 中使用回调机制更新 UI 的示例代码:
在 Service 中定义回调接口:
public interface OnUpdateUIListener {
void onUpdateUI ( String message) ;
}
Service 中保存回调对象并调用回调方法:
private OnUpdateUIListener mListener;
public void setOnUpdateUIListener ( OnUpdateUIListener listener) {
mListener = listener;
}
private void updateUI ( String message) {
if ( mListener != null ) {
mListener. onUpdateUI ( message) ;
}
}
Activity 实现回调接口并传递给 Service :
public class MainActivity extends AppCompatActivity implements Service. OnUpdateUIListener {
private MyService mService;
@Override
protected void onCreate ( Bundle savedInstanceState) {
super . onCreate ( savedInstanceState) ;
setContentView ( R . layout. activity_main) ;
Intent intent = new Intent ( this , MyService . class ) ;
bindService ( intent, mConnection, Context . BIND_AUTO_CREATE) ;
}
private ServiceConnection mConnection = new ServiceConnection ( ) {
@Override
public void onServiceConnected ( ComponentName componentName, IBinder iBinder) {
MyService. LocalBinder binder = ( MyService. LocalBinder ) iBinder;
mService = binder. getService ( ) ;
mService. setOnUpdateUIListener ( MainActivity . this ) ;
}
@Override
public void onServiceDisconnected ( ComponentName componentName) {
mService = null ;
}
} ;
@Override
public void onUpdateUI ( String message) {
}
}
在 Activity 中,我们使用 `bindService ( ) ` 方法将 Activity 与 Service 绑定,并在 `onServiceConnected ( ) `
方法中获取到 Service 实例,然后将 Activity 作为回调对象传递给 Service 。在 Service 中,我们保存回调对象,并在需要更新 UI 时调用回调方法。在 Activity 中实现回调接口,并在回调方法中更新 UI。
(char) (‘a’ ^ ‘t’)计算流程
'a' ^ 't' 表示对字符'a' 和字符't' 进行按位异或运算。而在Java 中,char 类型的'a' 和't' 被转化为ASCII码值97 和116 。
以下是( char ) ( 'a' ^ 't' ) 的计算过程:
1. 将 'a' 和 't' 转化为对应的 ASCII 码:
'a' -- > 97 ( 二进制: 01100001 )
't' -- > 116 ( 二进制: 01110100 )
2. 对两个二进制数进行异或运算:
01100001
^ 01110100
-- -- -- --
00010101
得到的结果是二进制数 00010101 。
3. 把得到的二进制数转换为十进制,即: 00010101 = 21 。
4. 将十进制数21 转换为对应的 ASCII 字符:
( char ) 21 -- > '\u0015' (表示空格,十进制值为21 )。
因此,表达式 ( char ) ( 'a' ^ 't' ) 的结果为字符 '\u0015' 。
Byte转化二进制字符串
VSCode怎么配置Java环境
首先,您需要确保您已经安装了Java开发工具包(JDK)。然后,根据以下步骤配置Java环境:
1. 打开VSCode
2. 打开“扩展”面板,搜索并安装“Java Extension Pack”
3. 在VSCode中打开一个Java项目
4. 在底部状态栏找到并点击“Java SE”按钮
5. 选择您已经安装的JDK版本
6. 按照提示安装必要的扩展及工具包
7. 在VSCode中打开一个Java文件
8. 在文件顶部添加import语句
9. 单击文件顶部的“运行”按钮,或使用快捷键Shift + F10,在弹出的菜单中选择“运行Java文件”以测试您的环境。
希望这可以帮助您成功配置Java环境。
Android Studio 4.1.2如何将工程JDK环境更换为JDK11
您可以按照以下步骤将Android Studio工程的JDK环境更改为JDK 11:
1.首先,您需要下载和安装JDK 11。您可以访问Oracle官网下载JDK 11安装程序。
2.以管理员身份打开Android Studio,然后从菜单栏中选择“File”(文件)->“Project Structure”(项目结构)。
3.在左侧面板中选择“SDK Location”(SDK位置),然后在右侧面板中找到“JDK Location”(JDK位置)。
4.单击“…”按钮,选择安装JDK 11的路径,然后单击“OK”按钮。
5.点击“Apply”(应用)按钮,然后选择“Yes”(是)按钮。
6.稍等一会儿,直到Android Studio完成设置。
现在,Android Studio的工程环境就已经更改为JDK 11。请注意,在切换JDK版本后,有些库可能会出现兼容性问题。如果您的工程中出现兼容性问题,您可以尝试更新相关库或调整代码以解决问题。
如何将Android Studio内置JDK改为11:
1. 首先,您需要下载JDK 11并安装在您的计算机上。
2. 打开Android Studio并关闭所有打开的工程。
3. 找到您的Android Studio安装目录,然后导航至子目录“jre\jre”(例如C:\Program Files\Android\Android Studio\jre\jre)。
4. 备份文件夹中的所有文件(以防意外情况)。
5. 删除文件夹中的所有文件。
6. 复制并粘贴JDK 11安装目录中的所有文件到Android Studio的JRE文件夹中。
7. 重新启动Android Studio并打开您的工程。
8. 转到“File”(文件) -> “Project Structure”(项目结构) -> “SDK Location”(SDK位置)。
9. 确保“JDK location”(JDK位置)指向Android Studio JRE文件夹(例如,C:\Program Files\Android\Android Studio\jre\jre)。
10. 单击“OK”并等待Android Studio重新加载。
现在,您的Android Studio将使用JDK 11作为默认JRE了。
UbuntuJDK环境怎么从8升级到11
要将Ubuntu上的JDK从8升级到11,请按照以下步骤执行:
1. 首先,使用以下命令列出当前安装的所有JDK版本:
update-java-alternatives -l
2. 从上面的列表中选择要升级到的JDK版本。前往Oracle官网下载下载JDK 11安装包,获取下载链接:
https://www.oracle.com/java/technologies/javase-jdk11-downloads.html
3. 下载解压包并将其移动到 `/usr/lib/jvm` 目录中。您可以使用以下命令完成此操作:
cd ~/Downloads
sudo tar zxvf jdk-11.0.11_linux-x64_bin.tar.gz -C /usr/lib/jvm/
4. 在终端中输入以下命令,以使新的JDK版本成为默认版本:
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk-11.0.11/bin/java 1
sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk-11.0.11/bin/javac 1
sudo update-alternatives --install /usr/bin/jar jar /usr/lib/jvm/jdk-11.0.11/bin/jar 1
5. 最后,您可以使用以下命令验证新的JDK版本是否安装成功:
java -version
如果成功的话,你应该看到类似以下的输出:
java version "11.0.11" 2021-04-20 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.11+9-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.11+9-LTS, mixed mode)
恭喜,您已成功将Ubuntu上的JDK从8升级到11。
Android Studio配置Gradle7后如何引如自定义Framework.jar
在Android Studio中配置Gradle 7.x.x之后,引入自定义的Framework.jar的方式与之前版本略有不同,具体步骤如下:
1. 打开项目的 `build.gradle` 文件,将Gradle版本升级为7.x.x,例如:
dependencies {
classpath 'com.android.tools.build:gradle:7.0.2'
}
2. 将自定义的Framework.jar文件拷贝到项目目录的 `libs` 文件夹下。
3. 在 `build.gradle` 文件中添加以下内容:
repositories {
flatDir {
dirs 'libs'
}
}
这个配置告诉Gradle,在 `libs` 文件夹下查找本地的jar文件。
4. 在项目的 `app/build.gradle` 文件中添加以下依赖:
dependencies {
implementation (name: 'Framework', ext: 'jar')
}
这个依赖会在项目构建时自动包含Framework.jar文件。
5. 最后,重新构建项目即可。如果一切顺利,您就可以在项目中使用自定义的Framework.jar了。
这就是在Android Studio中配置Gradle 7.x.x之后引入自定义的Framework.jar的方法。需要注意的是,如果您的Framework.jar文件中包含了一些Android SDK中已经存在的类,那么您可能会遇到命名冲突的问题,需要进行一些调整。