首页 > 解决方案 > how to check whether asynctask is finshed or not from another class

问题描述

i have one fragment which run asynctask to get data by parsing api and storing in array list.

but what i want to do is that i want to print that list from another class so that i can create search filter.

package com.example.rsquare_android_fixed.mywork.building

import android.os.AsyncTask
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.size
import androidx.fragment.app.Fragment
import com.example.rsquare_android_fixed.R
import com.example.test.mainF.Address_data
import kotlinx.android.synthetic.main.fragment_building.*
import org.json.JSONArray
import org.json.JSONObject
import java.net.HttpURLConnection
import java.net.URL

class buildingFragment: Fragment(){

    private val list=ArrayList<Address_data>()
    private val list2=ArrayList<Address_map>()
    public var list3=ArrayList<Address_all>()
    public var check_list3:Int = 0


    override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?): View? {


        val inflate=inflater.inflate(R.layout.fragment_building, container, false)

        val url="https://manage-dev.rsquare.co.kr/api/sample/buildings"

        AsyncTaskHandleJson().execute(url)
        return inflate
    }

    inner class AsyncTaskHandleJson: AsyncTask<String, String, String>(){
        override fun doInBackground(vararg url: String?): String {
            var text:String
            val connection= URL(url[0]).openConnection() as HttpURLConnection

            try{
                connection.connect()
                text=connection.inputStream.use{it.reader().use{reader->reader.readText()}}
            }
            finally{
                connection.disconnect()
            }

            return text
        }

        override fun onPostExecute(result: String?) {
            super.onPostExecute(result)
            handleJson(result)

            naverGeo()
        }

        //json parsing
        private fun handleJson(jsonString: String?) {
            val jsonArray= JSONArray(jsonString)
            //val list=ArrayList<Address_data>()
            var x=0
            while(x<jsonArray.length()){
                val jsonObject=jsonArray.getJSONObject(x)
                list.add(
                    Address_data(
                        jsonObject.getString("address"),
                        jsonObject.getString("bunji"),
                        jsonObject.getString("streetAddress"),
                        jsonObject.getString("updateAt")
                    )
                )
                x++
            }
            val adapter=MW_Adapter_list(requireActivity(),list)
            data_list.adapter=adapter

//            val a = list[0]
//            a.address
            list.forEach { println(it) }
            println("listsize1="+list.size)

        }
    }

    
    fun naverGeo(){
        println("naverGeo")
        var query:String
        println("listsize2="+list.size)
        for(i in 0..list.size-1){
            var a = list[i]
            query=a.address

            println("test  : $i")
            println("query : $query")
            var url2 = "https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode?X-NCP-APIGW-API-KEY-ID=key&X-NCP-APIGW-API-KEY=pw&query="+query

            AsyncTaskNaver().execute(url2)
        }
    }

    inner class AsyncTaskNaver:AsyncTask<String,String,String>(){
        override fun doInBackground(vararg url2: String?): String {
            var text:String
            val connection=URL(url2[0]).openConnection() as HttpURLConnection

            try{
                connection.connect()
                text=connection.inputStream.use{it.reader().use{reader->reader.readText()}}
            }
            finally{
                connection.disconnect()
            }
            return text
        }

        override fun onPostExecute(result: String?) {
            super.onPostExecute(result)
            handleJson2(result)

            //merge to longitude and latitude with original data
            if(list2.size==30){
                mergeList()
            }
        }
        private fun handleJson2(jsonString: String?){
            val jsonObj=JSONObject(jsonString)
            val jsonArray=JSONArray(jsonObj.get("addresses").toString())
            var x=0
            while(x<jsonArray.length()){
                val jsonObject=jsonArray.getJSONObject(x)
                list2.add(
                    Address_map(
                        jsonObject.getString("roadAddress"),
                        jsonObject.getString("x"), //long
                        jsonObject.getString("y") //lat
                    )
                )
                x++
            }
            //println(list2.size)
        }
    }


    fun mergeList(){
        //println(list2.size)
        for (i in 0..list.size-1){
            var list_api=list[i]
            var list_naver=list2[i]
            var query_api=list_api.address
            var query_naver=list_naver.raddress
            var bunji_api=list_api.bunji
            var street_api=list_api.streeetAddress
            var long_naver=list_naver.x
            var lat_naver=list_naver.y

            //by comparing first 2 letters, last 3 letters from address to merge them into one
            if(query_api.takeLast(3)==query_naver.takeLast(3)&&query_api.take(2)==query_naver.take(2)){
                list3.add(
                    Address_all(
                        query_api,
                        bunji_api,
                        street_api,
                        long_naver,
                        lat_naver
                    )
                )
            }

        }
        check_list3=1
        list3.forEach { println(it) }

    }

}

and below is my another code where i want to print list

package com.example.rsquare_android_fixed.mywork.search

import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.widget.ListView
import android.widget.TextView
import androidx.appcompat.widget.SearchView
import androidx.fragment.app.Fragment
import com.example.rsquare_android_fixed.R
import com.example.rsquare_android_fixed.mywork.building.MWFragment
import com.example.rsquare_android_fixed.mywork.building.MW_Adapter_list
import com.example.rsquare_android_fixed.mywork.building.buildingFragment
import com.naver.maps.geometry.LatLng
import com.naver.maps.geometry.LatLngBounds
import com.naver.maps.map.NaverMap
import com.naver.maps.map.NaverMapSdk
import com.naver.maps.map.overlay.Marker
import kotlinx.android.synthetic.main.fragment_building.*
import kotlinx.android.synthetic.main.fragment_search.*
import kotlinx.android.synthetic.main.list_search.*


class searchFragment: Fragment(){

    private var list: ListView?=null
    private var adapter:SearchAdapter?=null
    private var editsearch:SearchView?=null
    private var addrList:Array<String>?=null
    //lateinit var naverMap:NaverMap

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view:View = inflater.inflate(R.layout.fragment_search, container, false)

        //list=findViewById(R.id.search_list) as ListView

        val a = buildingFragment()
        if(a.check_list3==0){
            println("nulnunlnlunlnl")
        }
        else{
            println(a.list3)
            println("not null")
            //println(a.list3)
        }
        return view
    }

    /*override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

        super.onViewCreated(view, savedInstanceState)

        //NaverMapSdk.getInstance(requireContext()).client=NaverMapSdk.NaverCloudPlatformClient("dp3mci4foz")

        val a = buildingFragment()

    }

     */

}

i think my 2nd code is calling list before asynctask from 1st code is done. and this leads me to print null list.

so is there any method that 2nd code to notice that 1st code has finished asynctask?

(sry my code is way to dirty)

标签: androidkotlin

解决方案


创建接口

interface CallBack {
    fun asyncompleted(list:ArrayList<Address_all>)
}

在 searchFragment 中实现。

class searchFragment: Fragment(), CallBack {
    fun asyncCompleted(list:ArrayList<Address_all>) {
      println(list)
   }
}

在 buildingFragment 中创建方法

var callback: CallBack 
setCallback(value) { callback = value }  

在 searchFragment 中创建 buildingFragment 实例后设置回调

val a = buildingFragment()
a.setCallback(this)

设置 list3 后调用 asynccompleted 方法

override fun onPostExecute(result: String?) {
        super.onPostExecute(result)
        handleJson2(result)

        //merge to longitude and latitude with original data
        if(list2.size==30){
            mergeList()
        }
        callback.asyncompleted(list3)
 }

推荐阅读