[英]Unable to populate ListView from AsyncTask
The error is System services not available to Activities before onCreate()
错误是
System services not available to Activities before onCreate()
Below is my AsyncTask (it is in another class in a separate file) GetWarehouseSales.java 下面是我的AsyncTask(在单独文件的另一个类中) GetWarehouseSales.java
public class GetWarehouseSales extends Activity {
private String TAG = GetWarehouseSales.class.getSimpleName();
private ListView lv;
private ProgressDialog pDialog;
private Activity activityContext;
//URL to get JSON details
private static String url = "http://192.168.0.1/mycc/retrieve_ws.php";
ArrayList<HashMap<String,String>> sales_details;
public GetWarehouseSales(Activity context){
this.activityContext = context;
sales_details = new ArrayList<>();
}
public void executeGWS(){
new RetrieveWarehouseSalesTask().execute();
}
public class RetrieveWarehouseSalesTask extends AsyncTask<Void,Void,Void>{
@Override
protected void onPreExecute(){
super.onPreExecute();
pDialog = new ProgressDialog(activityContext);
pDialog.setMessage("Getting you the best warehouse sales...");
pDialog.setCancelable(false);
pDialog.show();
}
@Override
protected Void doInBackground(Void... arg0){
HttpHandler sh = new HttpHandler();
//making a request to URL and getting response
String jsonStr = sh.makeServiceCall(url);
Log.e(TAG, "Response from url: " + jsonStr);
if(jsonStr != null){
try{
JSONObject jsonObj = new JSONObject(jsonStr);
//Getting JSON Array Node
JSONArray sales = jsonObj.getJSONArray("Result");
//looping through all results
for(int i = 0; i<sales.length();i++){
JSONObject s = sales.getJSONObject(i);
String title = s.getString("title");
String description = s.getString("description");
HashMap<String,String> salesDetails = new HashMap<>();
//adding each child node to HashMap key =>value
salesDetails.put("title",title);
salesDetails.put("description",description);
//adding to array list
sales_details.add(salesDetails);
}
Log.d("TAG",sales_details.toString());
}catch(final JSONException e){
Log.e(TAG, "JSON parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(),"JSON parsing error: " + e.getMessage(),Toast.LENGTH_LONG).show();
}
});
}
}else{
Log.e(TAG,"Couldn't get json from server");
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "Check logcat", Toast.LENGTH_LONG ).show();
}
});
}
return null;
}
@Override
protected void onPostExecute(Void result){
super.onPostExecute(result);
if(pDialog.isShowing()){
pDialog.dismiss();
}
//update parsed JSON data into ListView
ListAdapter adapter = new SimpleAdapter(GetWarehouseSales.this, sales_details,R.layout.item_listview, new String[]{
"title","description"}, new int[]{R.id.text,R.id.description});
lv = (ListView)findViewById(R.id.list_item);
lv.setAdapter(adapter);
}
}
}
MainActivity.java MainActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
new GetWarehouseSales(this).executeGWS();
}
The error points to this line: 错误指向此行:
ListAdapter adapter = new SimpleAdapter(GetWarehouseSales.this, sales_details,R.layout.item_listview, new String[]{
"title","description"}, new int[]{R.id.text,R.id.description});
I am trying to populate the data into the listview but unable to do so. 我正在尝试将数据填充到listview中,但无法这样做。
Try to replace 尝试更换
new GetWarehouseSales(this).executeGWS();
to 至
executeGWS();
In general, you do it in the wrong way. 通常,您以错误的方式进行操作。 As I've already answered here NullPointerExeception for ProgressDialog in AsyncTask , you should define
AsynkTask
in the MainActivity
. 正如我已经在AsyncTask中为ProgressDialog的NullPointerExeception回答的那样 ,您应该在
MainActivity
定义AsynkTask
。
As Vasily Kabunov points out, don't create a new instance of the class to call the method. 正如Vasily Kabunov指出的那样,不要创建该类的新实例来调用该方法。 Also don't extend
Activity
when it is not an Activity
. 如果不是
Activity
,也不要扩展Activity
。
But also a major issue is doInBackground
should be building up a result that is then safely passed to the onPostExecute
, by writing to a field of the activity ( sales_details
), you have made this unthread-safe. 但是还有一个主要问题是
doInBackground
应该建立一个结果,然后将其安全地传递给onPostExecute
,方法是写入活动的字段( sales_details
),这使您成为非onPostExecute
安全的。
So do not access sales_details
or other activity fields in doInBackground
, do more like this: 因此,请勿访问
doInBackground
sales_details
或其他活动字段,执行以下操作:
public class RetrieveWarehouseSalesTask extends AsyncTask<Void,Void,ArrayList<HashMap<String,String>>>{ //return type set
@Override
protected ArrayList<HashMap<String,String>> doInBackground(Void... arg0){
ArrayList<HashMap<String,String>> result = new ArrayList<>();
...
//adding to array list
result.add(salesDetails);
...
return result;
}
@Override
protected void onPostExecute(ArrayList<HashMap<String,String>> result){
super.onPostExecute(result);
if(pDialog.isShowing()){
pDialog.dismiss();
}
//update parsed JSON data into ListView
ListAdapter adapter = new SimpleAdapter(GetWarehouseSales.this, result,R.layout.item_listview, new String[]{
"title","description"}, new int[]{R.id.text,R.id.description});
lv = (ListView)findViewById(R.id.list_item);
lv.setAdapter(adapter);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.