Android仿今日头条Kotlin版本
这是一款基于MVVM架构和Android Jetpack的商城+社交APP开发项目,使用Gradle 8.0和SDK 33编译。项目采用Apifox模拟服务器,包含即时通讯、第三方登录、支付等功能,但部分功能如注册需通过Apifox接口调试实现。开发中遇到的主要问题包括:1)SSL证书验证问题,通过自定义UnsafeSSLHelper解决;2)高德地图API冲突;3)定位显示优化;4)短视频SDK
软件信息
- gradle-8.0
- Sdk信息
//编译版本
compileSdk=33
//最小版本
minSdk=24
//目标版本
targetSdk=31 - Android Studio Giraffe | 2022.3.1 Patch 2(建议版本不要太低)
- MVVM
- Android Jetpack
项目注意
- 没有服务器,用的是Apifox模拟服务器返回,所以有的功能是不能测试的,比如注册等。
- 这是根据教学视频学习,码出来的项目,跟视频里面的一样。
- 通过https://sqlitebrowser.org/dl/下载工具,把手机/模拟器的data/data/包名/databases/.db文件打开进行查看数据库内容。
项目涉及功能
- 商城;
- 即时通讯;
- 微信、qq登录;
- 微信、支付宝支付等;
项目运行界面效果图
问题及解决
按照视频敲代码出现过的问题集合。某些问题是因为是用Apifox模拟服务器返回。只提供一种解决方法,不能保证最优,可作为参考。
1.问题:java.security.cert.CertificateException: Chain validation failed
解决:
object NetworkModule {
/**
* 提供OkHttpClient
*/
fun provideOkHttpClient(): OkHttpClient {
//初始化okhttp
val okhttpClientBuilder = OkHttpClient.Builder()
//新增下面这段
//接受自签名或不受信任的证书。这通常用于开发环境或内部测试,生产环境不建议使用
if (Config.DEBUG){
okhttpClientBuilder.sslSocketFactory(
UnsafeSSLHelper.createUnsafeSSLContext().socketFactory,
UnsafeSSLHelper.createUnsafeTrustManager()
)
okhttpClientBuilder.hostnameVerifier { _, _ -> true } // 跳过主机名验证
}
…………………………………………………………
}
}
class UnsafeSSLHelper {
companion object {
// 创建不安全的 TrustManager,接受所有证书
fun createUnsafeTrustManager(): X509TrustManager {
return object : X509TrustManager {
@Throws(CertificateException::class)
override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {
// 接受所有客户端证书
}
@Throws(CertificateException::class)
override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {
// 接受所有服务器证书
}
override fun getAcceptedIssuers(): Array<X509Certificate> {
return arrayOf()
}
}
}
// 创建不安全的 SSLContext
fun createUnsafeSSLContext(): SSLContext {
try {
val sslContext = SSLContext.getInstance("SSL")
sslContext.init(
null,
arrayOf<TrustManager>(createUnsafeTrustManager()),
SecureRandom()
)
return sslContext
} catch (e: Exception) {
throw RuntimeException(e)
}
}
}
}
2. 解决高德地图AMapUtilCoreApi、NetProxy类冲突
3.优化:发布界面进入“当前位置”一进来不显示PIO列表,如下左图优化成右图
解决:
步骤1:class SelectLocationActivity:AMap.OnMyLocationChangeListener{}
步骤2:binding.mapView.map.setOnMyLocationChangeListener(this)//设置定位监听
步骤3:
//实现 AMap.OnMyLocationChangeListener 监听器,通过如下回调方法获取经纬度信息:
override fun onMyLocationChange(location: Location?) {
location?.let {
searchPOI(
LatLng(
it.latitude,
it.longitude
), null
)
}
}
4.如何注册用户
解决:Apifox——》注册的接口——》修改参数——》发送,要执行成功才算。这样子就注册用户了。
5.关注用户一直失败,如何验证会话的功能。
前提分别登录用户A、B,其对应的userId分别为userIdA、userIdB.
步骤1:分别登录用户A、B,从AppContext.connectChat()方法里面成功回调得到的userIdA、userIdB。
步骤2:在ConversationActivity里面的initDatum()调用sendTextMessage(),这个是新增的,主要是为了能在会话列表界面有消息,才可以进入会话界面进行发送文字、图片。代码如下:
//TODO 测试发送信息
fun sendTextMessage() {
val content = "这是文本消息${System.currentTimeMillis()}"
var targetId = "0"
if (PreferenceUtil.getUserId() == "userIdA") {
targetId = "userIdB"
} else if (PreferenceUtil.getUserId() == "userIdB") {
targetId = "userIdA"
}
val conversationType = Conversation.ConversationType.PRIVATE//单聊
// 构建消息
val messageContent = TextMessage.obtain(content)
val message = Message.obtain(targetId, conversationType, messageContent)
// 发送消息
RongCoreClient.getInstance()
.sendMessage(message, null, null, object : IRongCoreCallback.ISendMessageCallback {
override fun onAttached(message: Message?) {
}
override fun onSuccess(message: Message?) {
Timber.d("sendTextMessage onSuccess %s", message.toString())
}
override fun onError(message: Message, errorCode: IRongCoreEnum.CoreErrorCode) {
Timber.d("sendTextMessage onError %s %d", message.toString(), errorCode.value)
}
})
}
6.接入短视频时出现:
java.lang.UnsatisfiedLinkError: No implementation found for void com.tencent.liteav.basic.datareport.TXCDRApi.nativeInitDataReport() (tried Java_com_tencent_liteav_basic_datareport_TXCDRApi_nativeInitDataReport and Java_com_tencent_liteav_basic_datareport_TXCDRApi_nativeInitDataReport__)

前提:运行在模拟器x86_64设备上的
解决:运行在"armeabi", "armeabi-v7a", "arm64-v8a"设备上(看腾讯云播放器SDK就知道为什么)
7.视频播放不出来。
前提:用Apifox等返回模拟数据,用的是开发环境
原因:返回的uri是news/news_3.mp4这种格式,经过处理后要播放的是http://***/news/news_3.mp4
解决:
方法1.修改返回的模拟数据uri为完整的可以网上播放是链接,且直接传it.uri而不是ResourceUtil.resourceUri(it.uri!!)
方法2.代码固定写死uri。
注网上可播放的视频链接如:https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/1080/Big_Buck_Bunny_1080_10s_1MB.mp4
效果:

8.学完74.2.继续学习Hilt注入框架运行一直报:服务异常、未知错误
如果直接拿项目的AddressNetworkService类过来运行,发现一直报:服务异常、未知错误等
原因:项目里面的AddressNetworkService写错了,可以去对比DefaultNetworkService类即可

注:视频里面addresses地址是写对了

9.学完76.1.实现缓存发现界面数据后
按照课程码出来或者直接从源码拿类过来,还是一直报错
D:\**\News\app\build\tmp\kapt3\stubs\devDebug\com\ixuea\courses\mymusic\component\content\Content.java:27: : Primary key constraint on id is ignored when being merged into com.ixuea.courses.mymusic.component.content.Content
private com.ixuea.courses.mymusic.component.user.User user;
^

解决步骤
1.修改room_version版本
原先:def room_version = "2.5.0"
改后:def room_version = "2.6.1"
2.修改compileSdk不低于34
解决后效果:

10.Could not find com.github.ctiao
Execution failed for task ':super-player-kit:compileDebugJavaWithJavac'.
> Could not resolve all files for configuration ':super-player-kit:debugCompileClasspath'.
> Could not find com.github.ctiao
解决:
弹幕0.9.25版本直报错:Could not find com.github.ctiao:DanmakuFlameMaster:0.9.25。故更换成0.3.8
未完待续
更多推荐


所有评论(0)