android - 应用程序在按钮单击调用服务时崩溃
问题描述
我正在制作一个批量重命名器,当我在选择文件后单击重命名按钮时,它应该调用后台服务来重命名它,同时显示通知,但应用程序在单击时崩溃。我在 android 5.0 上进行测试我尝试在开始时放置一条 toast 消息,但在此之前它崩溃了,我认为它在执行按钮单击事件之前崩溃了
来自崩溃的堆栈跟踪
04-09 20:19:00.077 834-1027/? E/ConnectivityService: RemoteException caught trying to send a callback msg for NetworkRequest [ id=143, legacyType=-1, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED] ]
04-09 20:25:47.388 834-1024/? E/WifiStateMachine: setSuspendOptimizationsNative: 4 false -want true stack:setSuspendOptimizationsNative - access$16400 - processMessage - processMsg
04-09 20:25:53.743 18486-18506/com.pride.msgshareapp E/[DRVB][EXT][UTIL]: disp_only_chk: DRVB CHECK0 PROCESS DONE ! STATUS (0x2000)
04-09 20:25:53.748 18486-18506/com.pride.msgshareapp E/GED: Failed to get GED Log Buf, err(0)
04-09 20:26:59.738 18486-18486/com.pride.msgshareapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.pride.msgshareapp, PID: 18486
java.lang.IndexOutOfBoundsException: Invalid index 2, size is 2
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:260)
at java.util.ArrayList.get(ArrayList.java:313)
at com.pride.msgshareapp.RenameOption$onCreate$5.onClick(RenameOption.kt:80)
at android.view.View.performClick(View.java:4848)
at android.view.View$PerformClick.run(View.java:20262)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5643)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
renamebtn.setOnClickListener {
val paramtxt = paratxt.text.toString().trim()
var reptxt = paramtxt
for(i in 0..cc)
{
reptxt = reptxt.replace("%title",seltitle[i],true)
reptxt = reptxt.replace("%album",selalbum[i],true)
reptxt = reptxt.replace("%artist",selartist[i],true)
resultt.add(reptxt)
}
val inte = Intent(this,RenameService::class.java)
inte.putExtra("path",selpath.toTypedArray())
inte.putExtra("newname",resultt.toTypedArray())
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
startForegroundService(inte)
}
else{
startService(inte)
}
}
服务代码
class RenameService : Service() {
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
val bundle: Bundle?=intent.extras
val pathss = bundle!!.getStringArray("path")
val namess = bundle!!.getStringArray("newname")
val resultt:MutableList<String> = mutableListOf()
val notifID = 595
val maxProgress = pathss.size
var currentProgress = 0
val inten = Intent(this, HobbiesActivity::class.java)
inten.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
val pendingIntent : PendingIntent = PendingIntent.getActivity(this,0,inten,0)
val builderr = NotificationCompat.Builder(this, "Renamer")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("Renaming " + pathss.size.toString() + " files")
.setContentText("Renaming....")
.setStyle(NotificationCompat.BigTextStyle()
.bigText("Renaming..."))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setVisibility(1)
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = "ChannelMain"
val descText = "Renaming Progress"
val imp = NotificationManager.IMPORTANCE_HIGH
val channel = NotificationChannel("Renamer", name, imp).apply {
description = descText
enableVibration(true)
}
val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
Toast.makeText(this,"Renaming",Toast.LENGTH_SHORT).show()
startForeground(notifID,builderr.build())
with(NotificationManagerCompat.from(this)){
builderr.setProgress(maxProgress, currentProgress, false)
notify(notifID, builderr.build())
for(i in 0..pathss.size)
{
if(renameTarget(pathss[i],namess[i])!=0)
{
resultt.add("Failed")
}
else
{
resultt.add("Success")
}
currentProgress = i
builderr.setContentText("Renaming " + i.toString() + " of " + pathss.size.toString())
builderr.setProgress(maxProgress,currentProgress,false)
notify(notifID,builderr.build())
}
builderr.setContentText("Rename Complete")
.setProgress(0,0,false)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
notify(notifID,builderr.build())
}
return Service.START_REDELIVER_INTENT
}
override fun onDestroy() {
super.onDestroy()
Toast.makeText(this,"Renaming completed",Toast.LENGTH_SHORT).show()
stopForeground(true)
}
override fun onTaskRemoved(rootIntent: Intent?) {
super.onTaskRemoved(rootIntent)
stopSelf()
}
}
fun renameTarget(filePath:String, newName:String):Int{
val src= File(filePath)
var ext=""
val dest: File
if(src.isFile)
{
ext=filePath.substring(filePath.lastIndexOf("."),filePath.length)
}
if(newName.isEmpty())
{
return -1
}
val temp=filePath.substring(0,filePath.lastIndexOf("/"))
dest= File("$temp/$newName$ext")
return if(src.renameTo(dest)) {
0
} else {
1
}
}
解决方案
该问题很可能是由以下行引起的:for(i in 0..cc)
. 原因是运算符..
创建了一个封闭范围,其中cc
包括在内,因此如果cc
等于您的列表/数组的大小,那么您将获得IndexOutOfBoundsException
. 要解决这个问题,您可以简单地将您的行更改为for (i in 0 until cc)
,因为该until
函数会创建一个不包括结束元素的范围。
推荐阅读
- unity3d - 如何通过脚本更改 Unity png 导入设置
- javascript - 如何读取表格中多个下拉列表中的选定选项?
- airflow - 执行任务后气流调度程序似乎没有运行
- javascript - 使用 React.js 进行 MSAL 身份验证和授权
- javascript - 具有特定限制的密码正则表达式
- java - 如何在android中使用rest api从服务器获取的图像滑块中传递动态图像链接
- laravel - 制作一个自定义模型,该模型将从另一个模型 laravel 5.8 获取数据
- react-native - 如何更改标记的颜色
- python - 如何在不访问其子标签文本的情况下获取父标签的文本?
- react-native - 在 react-native 中是否有将文本、图像转换为 pdf 的库?