[英]How should I implement my AsyncTask class?
我正在制作一个天气应用程序,我使用 AsyncTask 从 API 获取响应,然后设置 UI。 经过简单处理后,我的代码如下所示:
class MainActivity : AppCompatActivity() {
/*
SOME INSIGNIFICANT CODE HERE
*/
private fun setUI(currentWeather: Root){
tv_city.text = "${currentWeather.name}, ${currentWeather.sys.country}"
/*
...
*/
}
inner class WeatherByNameTask: AsyncTask<String, Unit, Unit>(){
override fun doInBackground(vararg p0: String?) {
val city: String? = p0[0]
val call = weatherApi.getCurrentWeatherByCityName(city!!, API_KEY, "metric")
call.enqueue(object: Callback<Root>{
override fun onResponse(call: Call<Root>, response: Response<Root>) {
if (!response.isSuccessful){
Toast.makeText(this@MainActivity, "Code: ${response.code()}", Toast.LENGTH_LONG).show()
} else {
val currentWeather = response.body()
setUI(currentWeather!!)
}
}
override fun onFailure(call: Call<Root>, t: Throwable) {
Toast.makeText(this@MainActivity, "Code: ${t.message}", Toast.LENGTH_LONG).show()
}
})
}
}
inner class WeatherByCoordTask: AsyncTask<Location, Unit, Unit>(){
override fun doInBackground(vararg p0: Location?) {
val lat: String = p0[0]?.latitude.toString()
val lon: String = p0[0]?.longitude.toString()
val call = weatherApi.getCurrentWeatherByCoordinates(lat, lon, API_KEY, "metric")
call.enqueue(object: Callback<Root>{
@SuppressLint("SetTextI18n")
override fun onResponse(call: Call<Root>, response: Response<Root>) {
if (!response.isSuccessful){
Toast.makeText(this@MainActivity, "Code: ${response.code()}", Toast.LENGTH_LONG).show()
} else {
val currentWeather = response.body()
setUI(currentWeather!!)
}
}
override fun onFailure(call: Call<Root>, t: Throwable) {
Toast.makeText(this@MainActivity, "Code: ${t.message}", Toast.LENGTH_LONG).show()
}
})
}
}
}
它有效,但我收到警告:
此 AsyncTask class 应为 static 否则可能会发生泄漏
我想以正确的方式做到这一点。 我试图在 MainActivity class 之外实现它,将上下文作为参数传递,但是 setUI function 呢? 我想公开它是个坏主意。
此 AsyncTask class 应为 static 否则可能会发生泄漏
在MainActivity
中,有 2 个带有inner
修饰符的AsyncTask
class,这意味着内部 class 将保持对外部 class 的强引用。 警告告诉您,当AsyncTask
在后台执行其工作时,如果用户离开当前活动(按 Back 键或调用finish()
方法),那么活动实例将被泄露,因为AsyncTask
仍然保持对它。
解决方案
使用WeakReference让AsyncTask
保持对MainActivity
的弱引用。
class WeatherByNameTask (activity: MainActivity): AsyncTask<String, Unit, Unit>(){
private val activityRef = WeakReference<MainActivity>(activity)
override fun doInBackground(vararg p0: String?) {
val city: String? = p0[0]
val call = weatherApi.getCurrentWeatherByCityName(city!!, API_KEY, "metric")
call.enqueue(object: Callback<Root>{
override fun onResponse(call: Call<Root>, response: Response<Root>) {
if (!response.isSuccessful){
activityRef.get()?.let {
Toast.makeText(it, "Code: ${response.code()}", Toast.LENGTH_LONG).show()
}
} else {
val currentWeather = response.body()
activityRef.get()?.setUI(currentWeather!!)
}
}
override fun onFailure(call: Call<Root>, t: Throwable) {
activityRef.get().let {
Toast.makeText(it, "Code: ${t.message}", Toast.LENGTH_LONG).show()
}
}
})
}
}
class WeatherByCoordTask (activity: MainActivity): AsyncTask<Location, Unit, Unit>(){
private val activityRef = WeakReference<MainActivity>(activity)
override fun doInBackground(vararg p0: Location?) {
val lat: String = p0[0]?.latitude.toString()
val lon: String = p0[0]?.longitude.toString()
val call = weatherApi.getCurrentWeatherByCoordinates(lat, lon, API_KEY, "metric")
call.enqueue(object: Callback<Root>{
@SuppressLint("SetTextI18n")
override fun onResponse(call: Call<Root>, response: Response<Root>) {
if (!response.isSuccessful){
activityRef.get()?.let {
Toast.makeText(it, "Code: ${response.code()}", Toast.LENGTH_LONG).show()
}
} else {
val currentWeather = response.body()
activityRef.get()?.setUI(currentWeather!!)
}
}
override fun onFailure(call: Call<Root>, t: Throwable) {
activityRef.get().let {
Toast.makeText(it, "Code: ${t.message}", Toast.LENGTH_LONG).show()
}
}
})
}
}
从活动中使用
val weatherByNameTask = WeatherByNameTask(this)
val weatherByCoordTask = WeatherByCoordTask(this)
以下是制作AsyncTask
的方法:
private class AsyncTaskGetPlaces extends AsyncTask<Void, Void, AsyncTaskResult<Object>>
{
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected AsyncTaskResult<Object> doInBackground(Void... params)
{
try
{
LibHttp libHttp = new LibHttp();
String res = libHttp.listBusiness("21","test@ns.com");
return new AsyncTaskResult<Object>(res);
}
catch (Exception e)
{
e.printStackTrace();
return new AsyncTaskResult<Object>(e);
}
}
@Override
protected void onPostExecute(AsyncTaskResult<Object> result)
{
if(result.getError()!= null)
{
showOKAlertMsg("App",getResources().getString(R.string.txt_data_not_found), false);
}
else
{
String res = result.getResult().toString();
try {
JSONObject resObj = new JSONObject(res);
if(resObj.getString("status_code").equals("1")){
//parse
// Do your task here
}
} catch (JSONException e) {
e.printStackTrace();
showOKAlertMsg("",getResources().getString(R.string.txt_internal_server_error), false);
}
}
}
}
AsyncTaskResult 在哪里
public class AsyncTaskResult<T>
{
private T result;
private Exception error;
public T getResult()
{
return result;
}
public Exception getError()
{
return error;
}
public AsyncTaskResult(T result)
{
this.result = result;
}
public AsyncTaskResult(Exception error)
{
this.error = error;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.