大佬教程收集整理的这篇文章主要介绍了将 android.content.Context 传递给挂起的函数会导致 android.os.NetworkOnMainThreadException,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个挂起的函数,它通过网络调用来获取一些数据并返回它。我正在使用 Volley。
class PokeClIEnt {
suspend fun getPokemonData(pokemonname: String,context: Context) = suspendCoroutIne<Pokemon> { cont ->
val queue = Volley.newrequestQueue(context)
val request = url.plus(pokemonName)
// some skipped code here
}
我在我的活动中这样调用它:
GlobalScope.launch {
val pokeResult = pokeClIEnt.getPokemonData(nameToSearch,applicationContext)
pokemonList.add(pokeResult)
pokemonAdapter.notifyItemInserted(pokemonList.size - 1)
}
然后我收到如下错误:androID.os.networkonmainthreadException
我怀疑这可能是因为我正在从 MainActivity 传递上下文,这不正确。这里的替代方案是什么?
谢谢,
安卓新手
更新:
class MainActivity : AppCompatActivity() {
overrIDe fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceStatE)
setContentVIEw(R.layout.activity_main)
val pokeClIEnt = PokeClIEnt()
var pokemonList = mutablelistof<Pokemon>()
val pokemonAdapter = PokemonRvAdapter(pokemonList)
val pokemonRv = findVIEwByID<RecyclerVIEw>(R.ID.rv_pokemon)
pokemonRv.adapter = pokemonAdapter
pokemonRv.layoutManager = linearlayoutmanager(this)
val searchbutton = findVIEwByID<button>(R.ID.search_btn)
searchbutton.setonClickListener {
val toast = Toast.makeText(applicationContext,"Loading poke data",Toast.LENGTH_SHORT)
toast.show()
val nameToSearch = findVIEwByID<EditText>(R.ID.search_pokemon_txt).text.toString().lowercase()
GlobalScope.launch(dispatchers.IO) {
val pokeResult = pokeClIEnt.getPokemonData(nameToSearch,applicationContext)
pokemonList.add(pokeResult)
pokemonAdapter.notifyItemInserted(pokemonList.size - 1)
}
}
}
}
PokeClIEnt:
const val url = "https://pokeAPI.co/API/v2/pokemon/"
class PokeClIEnt {
suspend fun getPokemonData(pokemonname: String,context: Context) = suspendCoroutIne<Pokemon> { cont ->
val queue = Volley.newrequestQueue(context)
val request = url.plus(pokemonName)
val Stringrequest = Stringrequest(request.Method.GET,request,Response.Listener<String> { response ->
val jObj = JsONObject(responsE)
val imgurl = jObj
.getJsONObject("Sprites")
.getJsONObject("other")
.getJsONObject("official-artwork")
.getString("front_default")
val inputStream = URL(imgurl).openStream()
/* call conTinuation.resume and pass your object */
cont.resume(Pokemon(name = jObj.getString("name"),image = BitmapFactory.decodeStream(inputStream)))
},Response.ErrorListener { err ->
cont.resumeWithException(err)
})
queue.add(Stringrequest)
}
}
根据 CommonsWare
评论,似乎 Dispatchers.IO
是您在这里所缺少的。准确地说,它应该是这样的:
GlobalScope.launch(Dispatchers.IO) {
val pokeResult = pokeClient.getPokemonData(nameToSearch,applicationContext)
pokemonList.add(pokeResult)
pokemonAdapter.notifyItemInserted(pokemonList.size - 1)
}
或
GlobalScope.launch {
withContext(Dispatchers.IO) {
val pokeResult = pokeClient.getPokemonData(nameToSearch,applicationContext)
pokemonList.add(pokeResult)
pokemonAdapter.notifyItemInserted(pokemonList.size - 1)
}
}
,
虽然我对 kotlin 完全不了解,但就我而言,当您在主线程上执行 Internet 相关操作(例如,从站点加载数据) 或您没有执行此操作时,会发生此错误在清单文件中声明了互联网权限。相反,您应该创建新线程并在那里执行操作。如果你不介意在这里添加 java 代码是一个片段
class getData implements Runnable{
@Override
public void run() {
//Do work over here such as loading date from url
runOnUiThread(new Runnable() {
@Override
public void run() {
//To update ui put code inside here
}
});
}
}
在主方法中使用这个:
Thread thread = new Thread(new getData());//use class name
thread.start();//To start execution
以上是大佬教程为你收集整理的将 android.content.Context 传递给挂起的函数会导致 android.os.NetworkOnMainThreadException全部内容,希望文章能够帮你解决将 android.content.Context 传递给挂起的函数会导致 android.os.NetworkOnMainThreadException所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。