我是Kotlin的新手,我正在尝试开发音乐应用程序。
我得到了这个我无法解决的错误。当我打开我的应用程序时,会显示歌曲列表,点击一首歌曲会重定向到现在播放的屏幕,但点击下一个或上一个按钮,我的应用程序崩溃。
logcat发出了一个我不明白的TypeCast错误。
守则如下:
class SongPlayingFragment : Fragment() {
var myActivity: Activity? = null
var mediaplayer: MediaPlayer? = null
var startTimeText: TextView? = null
var endTimeText: TextView? = null
var playpauseImageButton: ImageButton? = null
var previousImageButton: ImageButton? = null
var nextImageButton: ImageButton? = null
var loopImageButton: ImageButton? = null
var seekbar: SeekBar? = null
var songArtistView: TextView? = null
var songTitleView: TextView? = null
var shuffleImageButton: ImageButton? = null
var currentPosition: Int = 0
var fetchSongs: ArrayList<Songs>? = null
var currentSongHelper: CurrentSongHelper? = null
var audioVisualization: AudioVisualization? = null
var g1view: GLAudioVisualizationView? = null
object Staticated {
var MY_PREFS_SHUFFLE = "Shuffle Feature"
var MY_PREFS_LOOP = "Loop Feature"
}
var updateSongTime = object : Runnable {
override fun run() {
val getcurrent = mediaplayer?.currentPosition
startTimeText?.setText(String.format("%d:%d",
TimeUnit.MILLISECONDS.toMinutes(getcurrent?.toLong() as Long),
TimeUnit.MILLISECONDS.toSeconds(getcurrent?.toLong() as Long) -
TimeUnit.MILLISECONDS.toSeconds(TimeUnit.MILLISECONDS.toMinutes(getcurrent?.toLong() as Long)
)))
seekbar?.setProgress(getcurrent?.toInt() as Int)
Handler().postDelayed(this, 1000)
}
}
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
var view = inflater!!.inflate(R.layout.fragment_song_playing, container, false)
seekbar = view?.findViewById(R.id.seekBar)
startTimeText = view?.findViewById(R.id.startTime)
endTimeText = view?.findViewById(R.id.endTime)
playpauseImageButton = view?.findViewById(R.id.playPauseButton)
nextImageButton = view?.findViewById(R.id.nextButton)
previousImageButton = view?.findViewById(R.id.previousButton)
loopImageButton = view?.findViewById(R.id.LoopButton)
shuffleImageButton = view?.findViewById(R.id.shuffleButton)
songArtistView = view?.findViewById(R.id.songArtist)
songTitleView = view?.findViewById(R.id.songTitle)
g1view = view?.findViewById(R.id.visualizer_view)
return view
}
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
audioVisualization = g1view as AudioVisualization
}
override fun onAttach(context: Context?) {
super.onAttach(context)
myActivity = context as Activity
}
override fun onAttach(activity: Activity?) {
super.onAttach(activity)
myActivity = activity
}
override fun onResume() {
super.onResume()
audioVisualization?.onResume()
}
override fun onPause() {
audioVisualization?.onPause()
super.onPause()
}
override fun onDestroyView() {
audioVisualization?.release()
super.onDestroyView()
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
currentSongHelper = CurrentSongHelper()
currentSongHelper?.isPlaying = true
currentSongHelper?.isLoop = false
currentSongHelper?.isShuffle = false
var path: String? = null
var songTitle: String? = null
var songArtist: String? = null
var songId: Long = 0
try {
path = arguments.getString("path")
songTitle = arguments.getString("songTitle")
songArtist = arguments.getString("songArtist")
songId = arguments.getInt("songId").toLong()
currentPosition = arguments.getInt("songPosition")
fetchSongs = arguments.getParcelableArrayList("songData")
currentSongHelper?.songPath = path
currentSongHelper?.songTitle = songTitle
currentSongHelper?.songArtist = songArtist
currentSongHelper?.songId = songId
currentSongHelper?.currentPosition = currentPosition
updateTextViews(currentSongHelper?.songTitle as String, currentSongHelper?.songArtist as String)
} catch(e: Exception) {
e.printStackTrace()
}
mediaplayer = MediaPlayer()
mediaplayer?.setAudioStreamType(AudioManager.STREAM_MUSIC)
try {
mediaplayer?.setDataSource(myActivity, Uri.parse(path))
mediaplayer?.prepare()
} catch (e: Exception) {
e.printStackTrace()
}
mediaplayer?.start()
processInformation(mediaplayer as MediaPlayer)
if (currentSongHelper?.isPlaying as Boolean) {
playpauseImageButton?.setBackgroundResource(R.drawable.pause_icon)
} else {
playpauseImageButton?.setBackgroundResource(R.drawable.play_icon)
}
mediaplayer?.setOnCompletionListener {
onSongComplete()
}
clickHandler()
var visualizationHandler = DbmHandler.Factory.newVisualizerHandler(myActivity as Context, 0)
audioVisualization?.linkTo(visualizationHandler)
var prefsForShuffle = myActivity?.getSharedPreferences(Staticated.MY_PREFS_SHUFFLE, Context.MODE_PRIVATE)
var isShuffleAllowed = prefsForShuffle?.getBoolean("feature", false)
if (isShuffleAllowed as Boolean) {
currentSongHelper?.isShuffle = true
currentSongHelper?.isLoop = false
shuffleImageButton?.setBackgroundResource(R.drawable.shuffle_icon)
loopImageButton?.setBackgroundResource(R.drawable.loop_white_icon)
} else {
currentSongHelper?.isShuffle = false
shuffleImageButton?.setBackgroundResource(R.drawable.shuffle_white_icon)
}
var prefsForLoop = myActivity?.getSharedPreferences(Staticated.MY_PREFS_SHUFFLE, Context.MODE_PRIVATE)
var isLoopAllowed = prefsForShuffle?.getBoolean("feature", false)
if (isLoopAllowed as Boolean) {
currentSongHelper?.isShuffle = false
currentSongHelper?.isLoop = true
shuffleImageButton?.setBackgroundResource(R.drawable.shuffle_white_icon)
loopImageButton?.setBackgroundResource(R.drawable.loop_icon)
} else {
loopImageButton?.setBackgroundResource(R.drawable.loop_white_icon)
currentSongHelper?.isLoop = false
}
enter code here
}
fun clickHandler() {
shuffleImageButton?.setOnClickListener({
var editorShuffle = myActivity?.getSharedPreferences(Staticated.MY_PREFS_SHUFFLE, Context.MODE_PRIVATE)?.edit()
var editorLoop = myActivity?.getSharedPreferences(Staticated.MY_PREFS_LOOP, Context.MODE_PRIVATE)?.edit()
if (currentSongHelper?.isShuffle as Boolean) {
shuffleImageButton?.setBackgroundResource(R.drawable.shuffle_white_icon)
currentSongHelper?.isShuffle = false
editorShuffle?.putBoolean("feature", false)
editorShuffle?.apply()
} else {
currentSongHelper?.isShuffle = true
currentSongHelper?.isLoop = false
shuffleImageButton?.setBackgroundResource(R.drawable.shuffle_icon)
loopImageButton?.setBackgroundResource(R.drawable.loop_white_icon)
editorShuffle?.putBoolean("feature", true)
editorShuffle?.apply()
editorLoop?.putBoolean("feature", false)
editorLoop?.apply()
}
})
nextImageButton?.setOnClickListener({
currentSongHelper?.isPlaying = true
if (currentSongHelper?.isShuffle as Boolean) {
playNext("PlayNextLikeNormalShuffle")
} else {
playNext("PlayNextNormal")
}
})
previousImageButton?.setOnClickListener({
currentSongHelper?.isPlaying = true
if (currentSongHelper?.isLoop as Boolean) {
loopImageButton?.setBackgroundResource(R.drawable.loop_white_icon)
}
playPrevious()
})
loopImageButton?.setOnClickListener({
var editorShuffle = myActivity?.getSharedPreferences(Staticated.MY_PREFS_SHUFFLE, Context.MODE_PRIVATE)?.edit()
var editorLoop = myActivity?.getSharedPreferences(Staticated.MY_PREFS_LOOP, Context.MODE_PRIVATE)?.edit()
if (currentSongHelper?.isLoop as Boolean) {
currentSongHelper?.isLoop = false
loopImageButton?.setBackgroundResource(R.drawable.loop_white_icon)
editorLoop?.putBoolean("feature", false)
editorLoop?.apply()
} else {
currentSongHelper?.isLoop = true
currentSongHelper?.isShuffle = false
loopImageButton?.setBackgroundResource(R.drawable.loop_icon)
shuffleImageButton?.setBackgroundResource(R.drawable.shuffle_white_icon)
editorShuffle?.putBoolean("feature", false)
editorShuffle?.apply()
editorLoop?.putBoolean("feature", true)
editorLoop?.apply()
}
})
playpauseImageButton?.setOnClickListener({
if (mediaplayer?.isPlaying as Boolean) {
mediaplayer?.pause()
currentSongHelper?.isPlaying = false
playpauseImageButton?.setBackgroundResource(R.drawable.play_icon)
} else {
mediaplayer?.start()
currentSongHelper?.isPlaying = true
playpauseImageButton?.setBackgroundResource(R.drawable.pause_icon)
}
})
}
fun playNext(check: String) {
if (check.equals("PlayNextNormal", true)) {
currentPosition = currentPosition + 1
} else if (check.equals("PlayNextLikeNormalShuffle", true)) {
var randomObject = Random()
var randomPosition = randomObject.nextInt(fetchSongs?.size?.plus(1) as Int)
currentPosition = randomPosition
}
if (currentPosition == fetchSongs?.size) {
currentPosition = 0
}
currentSongHelper?.isLoop = false
var nextSong = fetchSongs?.get(currentPosition)
currentSongHelper?.songPath = nextSong?.songData
currentSongHelper?.songTitle = nextSong?.songTitle
currentSongHelper?.currentPosition = currentPosition
currentSongHelper?.songId = nextSong?.songId as Long
updateTextViews(currentSongHelper?.songTitle as String, currentSongHelper?.songArtist as String)
mediaplayer?.reset()
try {
mediaplayer?.setDataSource(myActivity, Uri.parse(currentSongHelper?.songPath))
mediaplayer?.prepare()
mediaplayer?.start()
processInformation(mediaplayer as MediaPlayer)
} catch (e: Exception) {
e.printStackTrace()
}
}
fun playPrevious() {
currentPosition = currentPosition - 1
if (currentPosition == -1) {
currentPosition = 0
}
if (currentSongHelper?.isPlaying as Boolean) {
playpauseImageButton?.setBackgroundResource(R.drawable.pause_icon)
} else {
playpauseImageButton?.setBackgroundResource(R.drawable.play_icon)
}
currentSongHelper?.isLoop = false
var nextSong = fetchSongs?.get(currentPosition)
currentSongHelper?.songPath = nextSong?.songData
currentSongHelper?.songTitle = nextSong?.songTitle
currentSongHelper?.currentPosition = currentPosition
currentSongHelper?.songId = nextSong?.songId as Long
updateTextViews(currentSongHelper?.songTitle as String, currentSongHelper?.songArtist as String)
mediaplayer?.reset()
try {
mediaplayer?.setDataSource(activity, Uri.parse(currentSongHelper?.songPath))
mediaplayer?.prepare()
mediaplayer?.start()
processInformation(mediaplayer as MediaPlayer)
} catch (e: Exception) {
e.printStackTrace()
}
}
fun onSongComplete() {
if (currentSongHelper?.isShuffle as Boolean) {
playNext("PlayNextLikeNormalShuffle")
currentSongHelper?.isPlaying = true
} else {
if (currentSongHelper?.isLoop as Boolean) {
currentSongHelper?.isPlaying = true
var nextSong = fetchSongs?.get(currentPosition)
currentSongHelper?.songTitle = nextSong?.songTitle
currentSongHelper?.songPath = nextSong?.songData
currentSongHelper?.currentPosition = currentPosition
currentSongHelper?.songId = nextSong?.songId as Long
updateTextViews(currentSongHelper?.songTitle as String, currentSongHelper?.songArtist as String)
mediaplayer?.reset()
try {
mediaplayer?.setDataSource(myActivity, Uri.parse(currentSongHelper?.songPath))
mediaplayer?.prepare()
mediaplayer?.start()
} catch (e: Exception) {
e.printStackTrace()
}
} else {
playNext("PlayNextNormal")
currentSongHelper?.isPlaying = true
}
}
}
fun updateTextViews(songtitle: String, songArtist: String) {
songTitleView?.setText(songtitle)
songArtistView?.setText(songArtist)
}
fun processInformation(mediaPlayer: MediaPlayer) {
val finalTime = mediaPlayer.duration
val startTime = mediaPlayer.currentPosition
seekbar?.max = finalTime
startTimeText?.setText(String.format("%d: %d",
TimeUnit.MILLISECONDS.toMinutes(startTime.toLong()),
TimeUnit.MILLISECONDS.toSeconds(startTime.toLong()) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(startTime?.toLong()))
))
endTimeText?.setText(String.format("%d:%d",
TimeUnit.MILLISECONDS.toMinutes(finalTime.toLong()),
TimeUnit.MILLISECONDS.toSeconds(finalTime.toLong()) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(finalTime?.toLong())))
)
seekbar?.setProgress(startTime)
Handler().postDelayed(updateSongTime, 1000)
}
}
日志:
12-07 20:30:27.447 28230-28230/com.example.sanjanaadmin.echo E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.sanjanaadmin.echo, PID: 28230
kotlin.TypeCastException: null cannot be cast to non-null type kotlin.String
at com.example.sanjanaadmin.echo.fragments.SongPlayingFragment.playNext(SongPlayingFragment.kt:314)
at com.example.sanjanaadmin.echo.fragments.SongPlayingFragment$clickHandler$2.onClick(SongPlayingFragment.kt:250)
at android.view.View.performClick(View.java:5268)
at android.view.View$PerformClick.run(View.java:21550)
at android.os.Handler.handleCallback(Handler.java:822)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5811)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:681)
答案 0 :(得分:7)
您正在尝试将safe call (?.
)生成的可为空的值转换为非空类型String
:
currentSongHelper?.songTitle as String
(以及其他几个地方)
如果值为null,则此强制转换将失败。要解决此问题,请转换为可为空的类型String?
:
currentSongHelper?.songTitle as String?
(也解决其他此类情况)
答案 1 :(得分:-2)
您也可以尝试以下解决方案之一:
提供默认值
currentSongHelper?.songTitle?:"default song title"
抛出内联异常
currentSongHelper?.songTitle?: throw NullpointerException("title is null")
安全演员
currentSongHelper?.songTitle as? String