我有两个数组(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));
}
}
答案 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<>();
}
}
}