AndroidStudio使用问题记录
学习文档
依赖
布局
implementation 'androidx.percentlayout:percentlayout:1.0.0'
网络
implementation 'com.squareup.okhttp3:okhttp:4.9.1'
增加权限
<uses-permission android:name="android.permission.INTERNET" />
测试代码
Log.i("Main", "开始测试网络请求");
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://www.baidu.com")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
// 处理请求失败
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
// 处理成功响应
String responseData = response.body().string();
// 在这里处理响应数据
Log.i("Mast", responseData);
}
});
问题
android studio logcat 无日志 No connect devices
无法看到日志
- [(27条消息) Android日志进阶篇]一-使用 Logcat 写入和查看日志_android logcat_一只农民工的博客-CSDN博客
将依赖转入到libs中以方便内网开发
外网导出
以下是修改后的build.gradle(Module)文件中的代码:
...
dependencies {
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
...
}
configurations {
copyDependencies
copyDependencies.extendsFrom implementation
}
task copyDependencies(type: Copy) {
from configurations.copyDependencies
into 'libs'
}
这段代码首先创建了一个名为copyDependencies的新配置,并让它继承自implementation配置。然后,copyDependencies任务会从这个新配置中复制依赖项。
在gradle.properties中增加以下命令
org.gradle.java.home=D:/Program Files/Java/jdk-17.0.3.1/
再次运行./gradlew copyDependencies命令,这应该可以解决你的问题。
内网引用
在Android Studio中,你可以通过以下步骤来引入libs文件夹中的jar或aar包:
-
将你的jar或aar文件复制到你的项目的
libs文件夹中。 -
在你的
build.gradle(Module级别)文件中,添加以下代码:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
}
这段代码会告诉Gradle在libs文件夹中查找所有的jar和aar文件,并将它们添加为依赖。
- 最后,点击Android Studio的
Sync Project with Gradle Files按钮(或者使用File -> Sync Project with Gradle Files菜单项)来同步你的项目。
以上步骤完成后,你就可以在你的项目中使用libs文件夹中的jar或aar文件了。
滚动事件监听
package com.example.spzx;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
protected TitleBar titleBar;
private List itemList = new ArrayList();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
titleBar = (TitleBar) findViewById(R.id.title_bar);
titleBar.setTitleLeft(R.drawable.newlogo);
titleBar.hideLeftIv();
titleBar.setTitle("审批中心", 22, 10, 8);
try {
RenderItemsView();
} catch (IOException e) {
Log.e("Main", e.getMessage());
}
initView();
}
public void onClickItem(View v) {
Intent intent = new Intent(MainActivity.this, MainActivityList.class);
intent.putExtra("id", "");
startActivity(intent);
}
public void onClickYiban(View v) throws IOException {
// todo已办
RenderItemsView();
Log.i("Main", "ceshiceshi");
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://www.baidu.com")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
// 处理请求失败
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
// 处理成功响应
String responseData = response.body().string();
// 在这里处理响应数据
Log.i("Mast", responseData);
}
});
}
public void onClickDaiban(View v) throws IOException {
// todo待办
RenderItemsView();
}
private ItemAdapter adapter;
private void RenderItemsView() throws IOException {
// todo获得务列表数据
initItems();//初始化任务列表数据
adapter = new ItemAdapter(this, R.layout.content_item, itemList);
// ArrayAdapter adapter1 = new ArrayAdapter(this, android.R.layout.simple_list_item_1,buttons);//借助ArrayAdapter实现数据传递
//获得控件
ListView listView = (ListView) findViewById(R.id.item_list);
listView.setAdapter(adapter);//调用setAdapter方法
}
private void initItems() throws IOException {
itemList.clear();
itemList.add(new Item("ccc", "fh_巩文亮01", "2021-11-09 14:31:57", "待审批"));
itemList.add(new Item("ccc", "fh_巩文亮02", "2021-11-09 14:31:57", "待审批"));
itemList.add(new Item("ccc", "fh_巩文亮03", "2021-11-09 14:31:57", "待审批"));
itemList.add(new Item("ccc", "fh_巩文亮04", "2021-11-09 14:31:57", "待审批"));
itemList.add(new Item("ccc", "fh_巩文亮05", "2021-11-09 14:31:57", "待审批"));
}
private int count = 0;
private void initView() {
ListView listView = (ListView) findViewById(R.id.item_list);
// 如果不添加footView,最后一项未完全显示就会触发触底事件,此时如果展示的item高度比较高对用户体验很不友好
View footView = View.inflate(MainActivity.this, R.layout.loading, null);
TextView footText = footView.findViewById(R.id.loading);
listView.addFooterView(footView);
// listView触底事件
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState) {
// 滚动停止时
case SCROLL_STATE_IDLE:
// 判断是否滚动到底部
if (view.getLastVisiblePosition() == (view.getCount() - 1)) {
if (count < 50) {
for (int i = 0; i < 10; i++) {
itemList.add(new Item("ccc", "fh_巩文亮"+i, "2021-11-09 14:31:57", "待审批"));
}
count = itemList.size();
// 数据变化后通知adapter
adapter.notifyDataSetChanged();
} else {
// 模拟没有跟多数据了
footText.setVisibility(View.GONE);
Toast.makeText(MainActivity.this, "已经是最后一页了", Toast.LENGTH_SHORT).show();
}
}
break;
default:
break;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/loading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="加载中..."
android:gravity="center"
android:padding="5dp"/>
</LinearLayout>
全局异常记录
前言:
在开发中我们会遇到程序崩溃闪退的问题,但是不是每次崩溃闪退都能抓到报错的异常信息,为了方便程序开发调试,定位分析异常发生的原因,我们希望程序在崩溃闪退的时候能够把异常信息记录下来,方便我们后期分析。这时候我们可以用全局异常处理来实现异常信息记录的功能。
代码实现
- 创建异常处理类
CrashHandler,当程序发生Uncaught异常的时候,由该类来接管程序,并记录错误日志。
public class CrashHandler implements UncaughtExceptionHandler {
private static final String TAG = "MyCrash";
// 系统默认的UncaughtException处理类
private UncaughtExceptionHandler mDefaultHandler;
@SuppressLint("StaticFieldLeak")
private static CrashHandler instance = new CrashHandler();
private Context mContext;
// 用于格式化日期,作为日志文件名的一部分
private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
/**
* 保证只有一个CrashHandler实例
*/
private CrashHandler() {
}
/**
* 获取CrashHandler实例 ,单例模式
*/
public static CrashHandler getInstance() {
return instance;
}
/**
* 初始化
*/
public void init(Context context) {
mContext = context.getApplicationContext();
// 获取系统默认的UncaughtException处理器
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
// 设置该CrashHandler为程序的默认处理器
Thread.setDefaultUncaughtExceptionHandler(this);
}
/**
* 当UncaughtException发生时会转入该函数来处理
*/
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!handleException(ex) && mDefaultHandler != null) {
// 如果用户没有处理则让系统默认的异常处理器来处理
mDefaultHandler.uncaughtException(thread, ex);
} else {
SystemClock.sleep(3000);
// 退出程序
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
}
}
/**
* 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
*/
private boolean handleException(Throwable ex) {
if (ex == null)
return false;
try {
// 使用Toast来显示异常信息
new Thread() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(mContext, "很抱歉,程序出现异常,即将返回.",
Toast.LENGTH_LONG).show();
Looper.loop();
}
}.start();
// 保存日志文件
saveCrashInfoFile(ex);
SystemClock.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
/**
* 保存错误信息到文件中
*/
private void saveCrashInfoFile(Throwable ex) throws Exception {
StringBuilder sb = new StringBuilder();
try {
SimpleDateFormat sDateFormat = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
String date = sDateFormat.format(new Date());
sb.append("\r\n").append(date).append("\n");
Writer writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
ex.printStackTrace(printWriter);
Throwable cause = ex.getCause();
while (cause != null) {
cause.printStackTrace(printWriter);
cause = cause.getCause();
}
printWriter.flush();
printWriter.close();
String result = writer.toString();
sb.append(result);
writeFile(sb.toString());
} catch (Exception e) {
Log.e(TAG, "an error occurred while writing file...", e);
sb.append("an error occurred while writing file...\r\n");
writeFile(sb.toString());
}
}
private void writeFile(String sb) throws Exception {
String time = formatter.format(new Date());
String fileName = "crash-" + time + ".txt";
if (hasSdcard()) {
String path = getGlobalPath();
File dir = new File(path);
if (!dir.exists())
dir.mkdirs();
FileOutputStream fos = new FileOutputStream(path + fileName, true);
fos.write(sb.getBytes());
fos.flush();
fos.close();
}
}
// 异常log保存路径
private String getGlobalPath() {
return mContext.getExternalFilesDir("").getAbsolutePath() + "/Crash/";
}
// 判断是否存在sd卡
private boolean hasSdcard() {
return Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED);
}
}
2、自定义一个继承Application的全局入口MyApplication,注册异常处理类。
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
CrashHandler.getInstance().init(this);
}
}
3、在AndroidManifest.xml文件中注册自定义的Application。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.test">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:name="com.test.exception.handle.MyApplication"
android:allowBackup="false"
android:icon="@mipmap/logo_test"
android:keepScreenOn="true"
android:label="@string/app_name"
android:roundIcon="@mipmap/logo_test"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
<activity
android:name=".MainActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 程序员小航
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果