
Question:
In my doInBackground
I declare and Initialize db, I got an error which say type mismatch. What should I put instead of putting this
?
var dbHelper: MyDBHelper? = null
dbHelper = MyDBHelper(this)
What should I put, There say Required: Context!
And this is my async task code, That Problem at dbHelper = MyDBHelper(this)
.
private class UpgradeDB(textView: TextView?) : AsyncTask<String, String, String>() {
var innerTextView: TextView? = textView
override fun onPreExecute() {
innerTextView!!.visibility = View.VISIBLE
}
override fun doInBackground(vararg params: String): String? {
val filename = "eBOSSInv_Upgrade.sql"
val sdcard = Environment.getExternalStorageDirectory()
val file = File(sdcard, filename)
if (!file.exists()) isCancelled
try {
var dbHelper: MyDBHelper? = null
dbHelper = MyDBHelper(this)
dbHelper!!.writableDatabase.use { db ->
var intTotalLine = 0
var intLine = 1
BufferedReader(FileReader(file)).useLines { _ -> intTotalLine++ }
BufferedReader(FileReader(file)).use { r ->
r.lineSequence().forEach {
if (it.isNotEmpty()) {
db!!.execSQL(it)
publishProgress(String.format("Updating %s/%s records", intLine, intTotalLine))
intLine++
}
}
}
}
} catch (e: Exception) {
}
return null
}
override fun onProgressUpdate(vararg text: String) {
innerTextView!!.text = text[0]
}
override fun onPostExecute(result: String?) {
innerTextView!!.text = ""
}
override fun onCancelled() {
}
}
Answer1:You need to pass context
into Async Task
.
Example:
llUpdate.setOnClickListener {
UpgradeDB(txtUpdate!!, getApplication()).execute("", "", "")
}
Then in UpgradeDB
, initialize the context.
private class UpgradeDB(textView: TextView?, context: Context) : AsyncTask<String, String, String>() {
var innerTextView: TextView? = textView
var mContext:Context? = context // initialize context
}
And finally
dbHelper = MyDBHelper(mContext)
Answer2:It depends where you try to create this object. Unless you do it in a class that extends Context (like Activity) it is not supposed to work. You can try such construct:
There are two ways you gan go:
The simpler way: Declare your AsyncTask as inner class inside tour activity and reference context using label. To declare class as inner you need to place it inside another class and add <em>inner</em> keyowrd:
class A {
inner class B
}
Now you can reference context from inside your async task like that:
dbHelper = DbHelper([ActivityName]@this)
Nevertheless, this is easy way to cause a memory leak, you can read more here: <a href="https://stackoverflow.com/questions/46273753/android-asynctask-memory-leaks" rel="nofollow">Android AsyncTask memory leaks</a>
The better way is to extract AsyncTask to another class and pass an application context to it, instead of Activity.