我是Android开发的新手,我正在尝试编写一个小应用程序,它允许我获取外部JSON文件并解析它。我得到了这个工作,但如果我尝试在后台执行它AsyncTask
它将无法工作。 Eclipse给了我错误
对于LongOperation类型
,方法findViewById(int)未定义
在这一行:
TextView txtView1 =(TextView)findViewById(R.id.TextView01);
这是我的代码:
public class Main extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new LongOperation().execute();
}
}
class LongOperation extends AsyncTask<String, Void, String> {
private final Context LongOperation = null;
@Override
protected String doInBackground(String... params) {
try {
URL json = new URL("http://www.corps-marchia.de/jsontest.php");
URLConnection tc = json.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(tc.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
JSONArray ja = new JSONArray(line);
JSONObject jo = (JSONObject) ja.get(0);
TextView txtView1 = (TextView)findViewById(R.id.TextView01);
txtView1.setText(jo.getString("text") + " - " + jo.getString("secondtest"));
}
} catch (MalformedURLException e) {
Toast.makeText(this.LongOperation, "Malformed URL Exception: " + e, Toast.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(this.LongOperation, "IO Exception: " + e, Toast.LENGTH_LONG).show();
} catch (JSONException e) {
Toast.makeText(this.LongOperation, "JSON Exception: " + e, Toast.LENGTH_LONG).show();
}
return null;
}
@Override
protected void onPostExecute(String result) {
}
protected void onPreExecute() {
}
@Override
protected void onProgressUpdate(Void... values) {
ProgressDialog pd = new ProgressDialog(LongOperation);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage("Working...");
pd.setIndeterminate(true);
pd.setCancelable(false);
}
}
有关如何解决此问题的任何想法?
答案 0 :(得分:5)
这是你应该做的,让它按你想要的方式工作。使用onPostExecute()
public class Main extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new LongOperation(this).execute();
}
}
class LongOperation extends AsyncTask<String, Void, String> {
private Main longOperationContext = null;
public LongOperation(Main context) {
longOperationContext = context;
Log.v("LongOper", "Konstuktor");
}
@Override
protected String doInBackground(String... params) {
Log.v("doInBackground", "inside");
StringBuilder sb = new StringBuilder();
try {
URL json = new URL("http://www.corps-marchia.de/jsontest.php");
URLConnection tc = json.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(tc.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
JSONArray ja = new JSONArray(line);
JSONObject jo = (JSONObject) ja.get(0);
Log.v("line = ", "jo.getString() ="+jo.getString("text"));
sb.append(jo.getString("text") + " - " + jo.getString("secondtest")).append("\n");
}
} catch (MalformedURLException e) {
e.printStackTrace();
Log.v("Error", "URL exc");
} catch (IOException e) {
e.printStackTrace();
Log.v("ERROR", "IOEXECPTOIn");
} catch (JSONException e) {
e.printStackTrace();
Log.v("Error", "JsonException");
}
String result = sb.toString();
return result;
}
@Override
protected void onPostExecute(String result) {
Log.v("onPostExe", "result = "+result);
TextView txtView1 = (TextView)longOperationContext.findViewById(R.id.textView01);
txtView1.setText(result);
}
protected void onPreExecute() {
}
@Override
protected void onProgressUpdate(Void... values) {
ProgressDialog pd = new ProgressDialog(longOperationContext);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage("Working...");
pd.setIndeterminate(true);
pd.setCancelable(false);
}
}
答案 1 :(得分:3)
你正在尝试做一些不起作用的事情。首先,你在一个扩展AsyncTask
的类中,因此你不会使用该方法,因为它是类Activity
的方法。
第二个问题是您正在尝试在与UI线程不同步的方法中执行UI内容。这不是你想做的事。
在doInBackground
方法中处理您的JSON响应,并将结果传递给onPostExecute
方法,在该方法中,您可以处理UI内容,因为它与UI线程同步。
您拥有的当前设置无法让您更轻松地处理您尝试执行的操作。您可以将LongOperation
类作为Activity
类的私有类,并将TextView
定义为实例成员。使用findViewById
内的OnCreate
将其从布局中删除,然后在onPostExecute
的{{1}}方法中修改(设置文字或其他内容)。
我希望我的意思有点清楚。
答案 2 :(得分:3)
其他一个答案中AsyncTask
的实施存在缺陷。每次在publishProgress
内创建进度对话框,并且在方法外部看不到对话框的引用。这是我的尝试:
public class Main extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new LongOperation().execute();
}
class LongOperation extends AsyncTask<String, Void, String> {
ProgressDialog pd = null;
TextView tv = null;
@Override
protected void onPreExecute(){
tv = Main.this.findViewById(R.id.textvewid);
pd = new ProgressDialog(Main.this);
pd.setMessage("Working...");
// setup rest of progress dialog
}
@Override
protected String doInBackground(String... params) {
//perform existing background task
return result;
}
@Override
protected void onPostExecute(String result){
pd.dismiss();
tv.setText(result);
}
}
}
答案 3 :(得分:2)
findViewById是Activity类中的方法。您应该在创建活动时将实例的实例传递给LongOperation。然后使用该实例调用findViewById。