Android:Kotlin TypeCastException:null无法强制转换为非null类型的kotlin.String

时间:2017-12-07 15:07:14

标签: android android-fragments kotlin

我是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)

2 个答案:

答案 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