android - 仅当添加 AdMob 时应用程序在首次打开时崩溃,但在下次打开时运行正常

标签 android android-layout kotlin admob banner

我的应用运行良好,然后我尝试添加 AdMob 依赖项。那时候事情就变得复杂了。在第一次安装然后打开应用程序崩溃。但在第二次和连续打开应用程序时运行正常,所有广告都在展示。

对我来说,这是一个糟糕的用户体验,因为第一次打开他们认为它不是一个好的应用程序。也许他们会立即卸载它。

也许我需要改进或添加一些东西,但我想不出来。我需要有关完善代码的帮助。

Android list

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gumangan.uecfispiritualhymns">

<uses-permission android:name="android.permission.INTERNET" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <!-- TODO: Change android:value when final building  -->
    <!--Sample AdMob App ID: ca-app-pub-3940256099942544~3347511713-->
    <meta-data
        android:name="com.google.android.gms.ads.APPLICATION_ID"
        android:value="ca-app-pub-3940256099942544~3347511713"/>

    <activity
        android:name="com.gumangan.uecfispiritualhymns.DictionaryActivity"
        android:label="@string/app_name"
        android:launchMode="singleTop"
        android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />

            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>

        <meta-data
            android:name="android.app.searchable"
            android:resource="@xml/searchable" />
    </activity>
    <activity 
android:name="com.gumangan.uecfispiritualhymns.WordDetailActivity"

android:parentActivityName="com.gumangan.uecfispiritualhymns.DictionaryActivity">

android:value="com.gumangan.uecfispiritualhymns.DictionaryActivity"/>
    </activity>
</application>

渐变属性

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
ext.kotlin_version = '1.3.10'
repositories {
    google()
    jcenter()
}
dependencies {
    classpath 'com.android.tools.build:gradle:3.2.1'
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
}
}

allprojects {
repositories {
    google()
    jcenter()
    maven {
        url "https://maven.google.com"
    }
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}

Gradle 依赖项

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

android {
compileSdkVersion 27
defaultConfig {
    applicationId "com.gumangan.uecfispiritualhymns"
    minSdkVersion 16
    targetSdkVersion 27
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.android.support:customtabs:27.1.1'

implementation 'com.google.android.gms:play-services-ads:17.1.2'

testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

数据库助手

package com.gumangan.uecfispiritualhymns

import android.content.Context
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.preference.PreferenceManager

import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.io.OutputStream

class DatabaseHelper(private var mContext: Context) : SQLiteOpenHelper(mContext, DATABASE_NAME, null, DATABASE_VERSION) {
companion object {
    private val DATABASE_NAME = "simple_dict.db"
    private val DATABASE_VERSION = 1
    val DB_CREATED = "DB_CREATED"
}

private var mCreateDb = false
private var mUpgradeDb = false

private fun copyDatabaseFromAssets(db: SQLiteDatabase?) {
    var inputStream: InputStream? = null
    var outputStream: OutputStream? = null

    try {
        inputStream = mContext.assets.open(DATABASE_NAME)
        outputStream = FileOutputStream(db?.path)

        val buffer = ByteArray(1024)
        var length: Int = inputStream!!.read(buffer)
        while (length > 0) {
            outputStream.write(buffer, 0, length)
            length = inputStream.read(buffer)
        }
        outputStream.flush()

        val  copiedDb = mContext.openOrCreateDatabase(DATABASE_NAME, 0, null)

        val isDbCreated = copiedDb != null

        copiedDb.execSQL("PRAGMA user_version = $DATABASE_VERSION")
        copiedDb.close()

        // DB_CREATED
        val sharedPref = PreferenceManager.getDefaultSharedPreferences(mContext)
        val sharePrefEditor = sharedPref.edit()
        sharePrefEditor.putBoolean(DB_CREATED, isDbCreated)
        sharePrefEditor.apply()
    } catch (e: IOException) {
        e.printStackTrace()
        throw Error("copyDatabaseFromAssets: Error copying database.")
    } finally {
        try {
            outputStream?.close()
            inputStream?.close()
        }catch (e: IOException) {
            e.printStackTrace()
            throw Error("copyDatabaseFromAssets: Error closing stream.")
        }
    }

}

override fun onCreate(db: SQLiteDatabase?) {
    mCreateDb = true
}

override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
    if(newVersion > oldVersion) {
        mUpgradeDb = true
    }
}

override fun onOpen(db: SQLiteDatabase?) {
    if(mCreateDb) {
        mCreateDb = false
        copyDatabaseFromAssets(db)
    }

    if(mUpgradeDb) {
        mUpgradeDb = false
        copyDatabaseFromAssets(db)
    }
}

fun getWords(wordPrefix: String = ""): Cursor {
    return if(wordPrefix.isBlank()) {
        readableDatabase.query(DictionaryEntryContract.TABLE_NAME, null,
                null, null, null, null,
                "${DictionaryEntryContract.COLUMN_ID} ASC")
    } else {
        readableDatabase.query(DictionaryEntryContract.TABLE_NAME, null,
                "${DictionaryEntryContract.COLUMN_WORD} LIKE ?", arrayOf("$wordPrefix%"),
                null, null, "${DictionaryEntryContract.COLUMN_ID} ASC")
    }
}

fun getWord(id: String): Cursor {
    return readableDatabase.query(DictionaryEntryContract.TABLE_NAME, null,
            "${DictionaryEntryContract.COLUMN_ID}= ?", arrayOf(id),
            null, null, null)
}
}

搜索列表适配器

package com.gumangan.uecfispiritualhymns

import android.content.Context
import android.database.Cursor
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.CursorAdapter
import android.widget.TextView

class SearchListAdapter(context: Context, cursor: Cursor) : CursorAdapter(context, cursor, 0) {
private class ViewHolder {
    var txtWord: TextView? = null
    var txtType: TextView? = null
    var txtMeaning: TextView? = null

    var wordColumnIndex: Int = 0
    var typeColumnIndex: Int = 0
    var meaningColumnIndex: Int = 0
}

override fun newView(context: Context?, cursor: Cursor?, parent: ViewGroup?): View {
    val layoutInflater = LayoutInflater.from(context)
    val newView = layoutInflater.inflate(R.layout.search_list_item, parent, false)

    val viewHolder = ViewHolder()
    viewHolder.txtWord = newView.findViewById<TextView>(R.id.txtWord)
    viewHolder.txtType = newView.findViewById<TextView>(R.id.txtType)
    viewHolder.txtMeaning = newView.findViewById<TextView>(R.id.txtMeaning)

    viewHolder.wordColumnIndex = cursor!!.getColumnIndexOrThrow(DictionaryEntryContract.COLUMN_WORD)
    viewHolder.typeColumnIndex = cursor!!.getColumnIndexOrThrow(DictionaryEntryContract.COLUMN_TYPE)
    viewHolder.meaningColumnIndex = cursor!!.getColumnIndexOrThrow(DictionaryEntryContract.COLUMN_MEANING)

    newView.tag = viewHolder

    return newView
}

override fun bindView(view: View?, context: Context?, cursor: Cursor?) {
    val viewHolder = view!!.tag as ViewHolder

    viewHolder.txtWord?.text = cursor?.getString(viewHolder.wordColumnIndex)
    viewHolder.txtType?.text = cursor?.getString(viewHolder.typeColumnIndex)
    viewHolder.txtMeaning?.text = cursor?.getString(viewHolder.meaningColumnIndex)
}

override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
    val view = super.getView(position, convertView, parent)

    if(position % 2 == 0) {
        view.setBackgroundColor(Color.LTGRAY)
    } else {
        view.setBackgroundColor(Color.WHITE)
    }

    return view;
}
}

DictionaryEntryContract

package com.gumangan.uecfispiritualhymns

import android.provider.BaseColumns

class DictionaryEntryContract : BaseColumns {
private constructor()

companion object {
    val TABLE_NAME = "english_words"

    val COLUMN_ID = BaseColumns._ID
    val COLUMN_WORD = "word"
    val COLUMN_TYPE = "type"
    val COLUMN_MEANING = "meaning"
}
}

DictionaryActivity

package com.gumangan.uecfispiritualhymns

import android.app.SearchManager
import android.content.Context
import android.content.Intent
import android.os.AsyncTask
import android.os.Bundle
import android.preference.PreferenceManager
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import android.support.v7.widget.SearchView
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.widget.AdapterView
import android.widget.ListView
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.AdView
import com.google.android.gms.ads.MobileAds
import java.lang.ref.WeakReference

class DictionaryActivity : AppCompatActivity() {

companion object {
    val TAG = "DictionaryActivity"
    val LAST_SEARCH_WORD: String = "LAST_SEARCH_WORD"
}

var mDbHelper: DatabaseHelper? = null
private var mSearchListAdapter: SearchListAdapter? = null
private var mSearchQuery: String = ""

//Google Ads Banner Variable
lateinit var mAdView : AdView

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.content_dictionary)

    mSearchQuery = savedInstanceState?.getString(LAST_SEARCH_WORD) ?: ""
    mDbHelper = DatabaseHelper(applicationContext)

    if(!isDbLoaded()) {
        showLoadingUI()
        LoadViewTask(this).execute()
    } else {
        showDictUI()
    }

    /* TODO: Change ADMOB ID's when final building  */
    //Google Ads
    //MobileAds.initialize(this, "ca-app-pub-3940256099942544~3347511713")
    //Google Test Ads
    MobileAds.initialize(this, "ca-app-pub-3940256099942544~3347511713")

    //Google Ads Banner
    mAdView = findViewById(R.id.adView)
    val adRequest = AdRequest.Builder().build()
    mAdView.loadAd(adRequest)

}

private fun isDbLoaded(): Boolean {
    val sharedPref = PreferenceManager.getDefaultSharedPreferences(this)
    return sharedPref.getBoolean(DatabaseHelper.DB_CREATED, false)
}

private fun showLoadingUI() {
    setContentView(R.layout.activity_dictionary_loading)
}

private fun showDictUI() {
    setContentView(R.layout.activity_dictionary)

    val toolbar = findViewById<Toolbar>(R.id.toolbar)
    setSupportActionBar(toolbar)

    supportActionBar?.setIcon(R.mipmap.ic_launcher)

    mSearchListAdapter = SearchListAdapter(applicationContext, mDbHelper!!.getWords(mSearchQuery))
    val lstWords = (findViewById<ListView>(R.id.lstWords))
    lstWords.adapter = mSearchListAdapter
    lstWords.onItemClickListener = AdapterView.OnItemClickListener { _, _, _, id ->
        val wordDetailIntent = Intent(applicationContext, WordDetailActivity::class.java)
        wordDetailIntent.putExtra(WordDetailActivity.WORD_ID, "$id")
        startActivity(wordDetailIntent)
    }
}

override fun onSaveInstanceState(outState: Bundle?) {
    super.onSaveInstanceState(outState)
    outState?.putString(LAST_SEARCH_WORD, mSearchQuery)
}

override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
    mSearchQuery = savedInstanceState?.getString(LAST_SEARCH_WORD) ?: ""
    super.onRestoreInstanceState(savedInstanceState)
}

override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)

    if(intent?.action.equals(Intent.ACTION_SEARCH)) {
        val searchQuery = intent?.getStringExtra(SearchManager.QUERY) ?: ""
        updateListByQuery(searchQuery)
    }
}

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.menu_dictionary, menu)

    val searchView: SearchView? = menu.findItem(R.id.action_search).actionView as? SearchView
    val searchManager: SearchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
    searchView?.setSearchableInfo(searchManager.getSearchableInfo(componentName))

    searchView?.setOnQueryTextListener(object : SearchView.OnQueryTextListener{
        override fun onQueryTextSubmit(query: String?): Boolean {
            return false
        }

        override fun onQueryTextChange(newText: String?): Boolean {
            updateListByQuery(newText ?: "")
            return true
        }
    })

    return true
}

private fun updateListByQuery(searchQuery: String) {
    mSearchQuery = searchQuery
    mSearchListAdapter?.changeCursor(mDbHelper!!.getWords(searchQuery))
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.action_search -> {
            onSearchRequested()
            true
        }
        else -> super.onOptionsItemSelected(item)
    }
}

private class LoadViewTask(activity: DictionaryActivity) : AsyncTask<Void, Void, Void>() {
    private var mActivity = WeakReference<DictionaryActivity>(activity)

    override fun doInBackground(vararg params: Void): Void? {
        if(getActivityInstance()?.mDbHelper?.readableDatabase?.isOpen == true) {
            Log.d(TAG, "Db is OK.")
        }
        return null
    }

    override fun onPostExecute(result: Void?) {
        if(getActivityInstance()?.isDbLoaded() == true) {
            getActivityInstance()?.showDictUI()
        }
    }

    private fun getActivityInstance() = mActivity.get()
}
}

WordDetailActivity

package com.gumangan.uecfispiritualhymns

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView

class WordDetailActivity : AppCompatActivity() {

companion object {
    const val WORD_ID = "WORD_ID"
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_word_detail)

    val wordId = intent.getStringExtra(WORD_ID) ?: ""
    if(wordId.isBlank()) {
        finish()
    }

    val dbHelper = DatabaseHelper(applicationContext)
    val cursor = dbHelper.getWord(wordId)
    if(cursor.moveToFirst()) {
        val txtWord = findViewById<TextView>(R.id.txtWord)
        val txtType = findViewById<TextView>(R.id.txtType)
        val txtMeaning = findViewById<TextView>(R.id.txtMeaning)

        txtWord?.text = cursor.getString(cursor.getColumnIndexOrThrow(DictionaryEntryContract.COLUMN_WORD))
        txtType?.text = cursor.getString(cursor.getColumnIndexOrThrow(DictionaryEntryContract.COLUMN_TYPE))
        txtMeaning?.text = cursor.getString(cursor.getColumnIndexOrThrow(DictionaryEntryContract.COLUMN_MEANING))
    }
}
}

activity_dictionary.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.gumangan.uecfispiritualhymns.DictionaryActivity">

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay" />

</android.support.design.widget.AppBarLayout>

<include layout="@layout/content_dictionary" />

</android.support.design.widget.CoordinatorLayout>

content_dictionary.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.gumangan.uecfispiritualhymns.DictionaryActivity"
tools:showIn="@layout/activity_dictionary">

<ListView
    android:id="@+id/lstWords"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginBottom="0dp"
    android:layout_marginEnd="0dp"
    android:layout_marginStart="0dp"
    android:layout_marginTop="0dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />


    <!--Google Ads Banner Display-->
    <com.google.android.gms.ads.AdView
        xmlns:ads="http://schemas.android.com/apk/res-auto"
        android:id="@+id/adView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="5dp"
        android:visibility="visible"
        ads:adSize="LARGE_BANNER"
        ads:adUnitId="ca-app-pub-3940256099942544/6300978111"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent">

    </com.google.android.gms.ads.AdView>

</android.support.constraint.ConstraintLayout>

activity_dictionary_loading.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.gumangan.uecfispiritualhymns.DictionaryActivity">

<TextView
    android:id="@+id/textView"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginStart="8dp"
    android:layout_marginTop="8dp"
    android:text="@string/dictionary_db_preparing"
    android:textAlignment="center"
    android:textSize="18sp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    tools:text="@string/dictionary_db_preparing" />
</android.support.constraint.ConstraintLayout>

search_list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">

<TextView
    android:id="@+id/txtWord"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="18sp"
    android:textStyle="bold"
    tools:text="Word" />

<TextView
    android:id="@+id/txtType"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="14sp"
    android:textStyle="italic"
    tools:text="Type" />

<TextView
    android:id="@+id/txtMeaning"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="18sp"
    tools:text="Meaning" />
</LinearLayout>

activity_word_detail.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
tools:context="com.gumangan.uecfispiritualhymns.WordDetailActivity">

<TextView
    android:id="@+id/txtWord"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="20sp"
    android:textStyle="bold"
    tools:text="Word" />

<TextView
    android:id="@+id/txtType"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="18sp"
    android:textStyle="italic"
    tools:text="Type" />

<TextView
    android:id="@+id/txtMeaning"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="20sp"
    tools:text="Meaning" />

</LinearLayout>

这是 LogCat 错误

12-09 07:52:40.554 14146-14146/com.gumangan.uecfispiritualhymns E/AndroidRuntime: FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.gumangan.uecfispiritualhymns/com.gumangan.uecfispiritualhymns.DictionaryActivity}: java.lang.IllegalStateException: findViewById(R.id.adView) must not be null
        at 
    android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
        at 
    android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
        at android.app.ActivityThread.access$600(ActivityThread.java:130)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4745)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.IllegalStateException: findViewById(R.id.adView) must not be null
        at com.gumangan.uecfispiritualhymns.DictionaryActivity.onCreate(DictionaryActivity.kt:57)
        at android.app.Activity.performCreate(Activity.java:5008)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084) 
        at android.app.ActivityThread.access$600(ActivityThread.java:130) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:137) 
        at android.app.ActivityThread.main(ActivityThread.java:4745) 
        at java.lang.reflect.Method.invokeNative(Native Method) 
        at java.lang.reflect.Method.invoke(Method.java:511) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
        at dalvik.system.NativeStart.main(Native Method) 

该应用程序是关于字典的

最佳答案

在您的 MainActivity.kt 中。尝试替换这个:

lateinit var mAdView: AdView

MobileAds.initialize(this, "ca-app-pub-3940256099942544~3347511713")

//Google Ads Banner
mAdView = findViewById(R.id.adView)
val adRequest = AdRequest.Builder().build()
mAdView.loadAd(adRequest)
mAdView.adListener = object: AdListener() {
    override fun onAdLoaded() {
        //adView.visibility = View.VISIBLE
        //divider.visibility = View.VISIBLE
        Toast.makeText(applicationContext,"Banner Ad Loaded", Toast.LENGTH_LONG).show()
    }
    override fun onAdFailedToLoad(errorCode : Int) {
        //adView.visibility = View.GONE
        //divider.visibility = View.GONE

        //Timer for Loading Ads
        Handler().postDelayed({

            mAdView.loadAd(adRequest)

        }, 300000)

        //mAdView.loadAd(adRequest)
        Toast.makeText(applicationContext,"Banner Ad Failed to Load", Toast.LENGTH_LONG).show()
    }
    override fun onAdOpened() {
        // Code to be executed when the ad is displayed.
    }
    override fun onAdLeftApplication() {
        // Code to be executed when the user has left the app.
    }
    override fun onAdClosed() {
        //mAdView.loadAd(adRequest)
        //Toast.makeText(applicationContext,"Banner Ad Loaded Again", Toast.LENGTH_LONG).show()
    }
}

用这个:

import kotlinx.android.synthetic.main.content_main.*

MobileAds.initialize(this,"ca-app-pub-3940256099942544~3347511713")

adView.loadAd(AdRequest.Builder().build())

并确保 adView 可见。

关于android - 仅当添加 AdMob 时应用程序在首次打开时崩溃,但在下次打开时运行正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53629859/

相关文章:

android - 为警报对话框设置 Android Theme.Light

android - 如何在 Android R 中设置全屏?

spring - Intellij 问题解决了 spring kotlin 的依赖关系

java - CustomView无法实例化(编辑器预览时出错,编译后不显示任何内容)

android - 如何在同一个 fragment 中创建多个 Retrofit 回调 - android

java - Android错误:找不到符号类LocationClient

java - Eclipse 在冷启动时不导入 java 库,以及其他编译错误

java - Android ImageView 克服线性布局

kotlin - 如何在 Kotlin 中获取通用参数类?

android - 无法在写入事务之外修改托管对象(Realm + Android)