如何使UI方法等待asynctask?

时间:2019-05-06 21:40:46

标签: java android android-asynctask

我有两个数组(groupID,groupNames),我需要填充从某些URL接收的变量,这是在扩展AsyncTask的子类内完成的,否则会导致NetworkOnMainThreadException错误。问题是我需要确保在UI线程中调用initRecyclerView();之前已填充了这两个数组。

如何确保我的代码在执行initRecyclerView();之前等待异步完成?

public class GroupPage extends AppCompatActivity {

    private static final String TAG = "RecycleViewAdapter";
    private ArrayList<Integer> groupIDs = new ArrayList<>();
    private ArrayList<String> groupNames = new ArrayList<>();

    private class groupPageConnect extends AsyncTask {
        @Override
        protected Object doInBackground(Object... arg0) {

            try{
                System.out.println("Testing 1 - Send Http GET request");
                getGroups();

            } catch (Exception e) {
                System.err.println("Oops!");
                e.printStackTrace();
            }
            return null;
        }
    }

    private void getGroups() throws Exception{
        String url = "http://obsco.me/obsco/api/v1.0/users/12345671";
        URL obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
        con.setRequestMethod("GET");
        con.setRequestProperty("User-Agent", "Mozilla/5.0");

        int responseCode = con.getResponseCode();
        System.out.println("Response Code  for IDs: " + responseCode);

        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();
        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

        JSONObject reader = new JSONObject(response.toString());
        JSONArray allContainingArray = reader.getJSONArray("users");
        JSONObject userJSON  = (JSONObject) allContainingArray.get(0);
        JSONArray temp = userJSON.getJSONArray("groups");

        Log.d(TAG, "initializing");
        for (int x = 0; x < temp.length(); x++){
            //System.out.println(temp.getJSONObject(x).getInt("id"));
            groupIDs.add(temp.getJSONObject(x).getInt("id"));
            System.out.println(groupIDs.size() );
            System.out.println(groupIDs.get(x));
            //groupNames.add("Dummy");

            url = "http://obsco.me/obsco/api/v1.0/groupname/" + groupIDs.get(x);
            System.out.println("ar1");
            obj = new URL(url);
            System.out.println("ar2");
            con = (HttpURLConnection) obj.openConnection();
            con.setRequestMethod("GET");
            con.setRequestProperty("User-Agent", "Mozilla/5.0");

            responseCode = con.getResponseCode();
            System.out.println("Response Code  for IDs: " + responseCode);

            in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            response = new StringBuffer();
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            reader = new JSONObject(response.toString());
            System.out.println(reader.getString("name"));
            groupNames.add(reader.getString("name"));
        }

    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_group_page);
        Log.d(TAG, "started");
        try {
            groupPageInit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void groupPageInit() throws Exception{
        new groupPageConnect().execute();
        initRecyclerView();
    }

    private void initRecyclerView(){
        Log.d(TAG, "initializingRecyclerView");
        RecyclerView recyclerView = findViewById(R.id.recycler_view);
        RecyclerViewAdapter adapter = new RecyclerViewAdapter( this, groupIDs, groupNames);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager( new LinearLayoutManager( this));
    }
}

4 个答案:

答案 0 :(得分:0)

getGroups()之后,您可以使用runOnUiThread()

示例:

getGroups();
runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // Logic that you want to execute on main thread
                        initRecyclerView();
                    }
                });

答案 1 :(得分:0)

在onPostExecute(result)方法上调用initRecyclerView()方法。异步任务由在后台线程上运行的计算定义,并且其结果发布在UI线程上。异步任务由4个步骤定义,这些步骤分别在后台计算完成后在UI线程上调用,分别称为onPreExecute,doInBackground,onProgressUpdate和onPostExecute.onPostExecute(Result)。

private class groupPageConnect extends AsyncTask<Object,void,String> {

        @Override
        protected Object doInBackground(Object... arg0) {
           //put your code here
        }

        @Override
        protected void onPostExecute(String result) {
             //call what you want to update
                        initRecyclerView();

            // dismiss progress dialog here
            // into onPostExecute() but that is upto you
        }

        @Override
        protected void onPreExecute() {
        // start progress dialog here
        }

        @Override
        protected void onProgressUpdate(Void... values) {
         // progress update here}
         }
     }

答案 2 :(得分:0)

您可以覆盖onPostExecute。

  

onPostExecute(Result),在后台计算完成后在UI线程上调用。后台计算的结果作为参数传递到此步骤。task goes through 4 steps

请注意,通过AsyncTask从网络加载数据可能是内存泄漏的原因。

答案 3 :(得分:0)

AsyncTask完成工作后,它将调用onPostExecute()方法来更新UI(根据您的情况在initRecyclerView()方法中执行代码)。另外,您应该使用WeakReference来防止泄漏GroupPage活动的上下文。

这是我的解决方法:

public class GroupPage extends AppCompatActivity {

    private static final String TAG = "RecycleViewAdapter";

    private ArrayList<Integer> groupIDs = new ArrayList<>();
    private ArrayList<String> groupNames = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_group_page);
        Log.d(TAG, "started");
        new GroupPageConnect(this).execute();
    }

    private void initRecyclerView(List<Integer> groupIds, List<String> groupNames) {
        this.groupIDs.addAll(groupIds);
        this.groupNames.addAll(groupNames);

        Log.d(TAG, "initializingRecyclerView");
        RecyclerView recyclerView = findViewById(R.id.recycler_view);
        RecyclerViewAdapter adapter = new RecyclerViewAdapter(this, this.groupIDs, this.groupNames);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
    }

    private static class GroupPageConnect extends AsyncTask<Void, Void, Group> {

        private WeakReference<GroupPage> mGroupPage;

        GroupPageConnect(GroupPage groupPage) {
            mGroupPage = new WeakReference<>(groupPage);
        }

        @Override
        protected Group doInBackground(Void... arg0) {
            try {
                System.out.println("Testing 1 - Send Http GET request");
                return getGroups();
            } catch (Exception e) {
                System.err.println("Oops!");
                e.printStackTrace();
                return null;
            }
        }

        private Group getGroups() throws Exception {
            Group group = new Group();

            String url = "http://obsco.me/obsco/api/v1.0/users/12345671";
            URL obj = new URL(url);
            HttpURLConnection con = (HttpURLConnection) obj.openConnection();
            con.setRequestMethod("GET");
            con.setRequestProperty("User-Agent", "Mozilla/5.0");

            int responseCode = con.getResponseCode();
            System.out.println("Response Code  for IDs: " + responseCode);

            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            JSONObject reader = new JSONObject(response.toString());
            JSONArray allContainingArray = reader.getJSONArray("users");
            JSONObject userJSON = (JSONObject) allContainingArray.get(0);
            JSONArray temp = userJSON.getJSONArray("groups");

            Log.d(TAG, "initializing");
            for (int x = 0; x < temp.length(); x++) {
                //System.out.println(temp.getJSONObject(x).getInt("id"));
                group.groupIds.add(temp.getJSONObject(x).getInt("id"));
                System.out.println(group.groupIds.size());
                System.out.println(group.groupIds.get(x));
                //groupNames.add("Dummy");

                url = "http://obsco.me/obsco/api/v1.0/groupname/" + group.groupIds.get(x);
                System.out.println("ar1");
                obj = new URL(url);
                System.out.println("ar2");
                con = (HttpURLConnection) obj.openConnection();
                con.setRequestMethod("GET");
                con.setRequestProperty("User-Agent", "Mozilla/5.0");

                responseCode = con.getResponseCode();
                System.out.println("Response Code  for IDs: " + responseCode);

                in = new BufferedReader(new InputStreamReader(con.getInputStream()));
                response = new StringBuffer();
                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();

                reader = new JSONObject(response.toString());
                System.out.println(reader.getString("name"));
                group.groupNames.add(reader.getString("name"));
            }

            return group;
        }

        @Override
        protected void onPostExecute(Group group) {
            super.onPostExecute(group);

            GroupPage groupPage = mGroupPage.get();
            if (group == null) {
                return;
            }

            groupPage.initRecyclerView(group.groupIds, group.groupNames);
        }
    }

    static class Group {
        List<Integer> groupIds;
        List<String> groupNames;

        Group() {
            groupIds = new ArrayList<>();
            groupNames = new ArrayList<>();
        }
    }
}