2011-02-12 102 views
5

我是Android新手,我試圖編寫一個小應用程序,它允許我抓取外部JSON文件並解析它。我得到了這個工作,但它不會工作,如果我試圖在後臺執行它作爲AsyncTask。蝕給我的錯誤findViewById(int)方法未定義

方法findViewById(INT)是未定義的類型LongOperation

在這一行

的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); 
    }  

} 

關於如何解決此問題的任何想法?

回答

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); 
     } 
    } 
} 
2

findViewById是Activity類中的方法。您應在創建活動時將您的活動實例傳遞給LongOperation。然後使用該實例調用findViewById。

+2

地方通過你的`Activity`類的實例是非常危險的,如果你不知道你在做什麼,你最終可能會泄露整個活動! – 2011-02-12 17:40:34

3

你正在嘗試做一些不起作用的東西。首先,您屬於擴展AsyncTask的類,因此您不會使用該方法,因爲它是類Activity的一種方法。

第二個問題是您正在嘗試在與UI線程不同步的方法中執行UI東西。這不是你想要做的。

doInBackground方法中處理您的JSON響應,並將結果傳遞給onPostExecute方法,在該方法中您將能夠處理與UI線程同步的UI內容。

當前的設置不會讓你更容易處理你想要做的事情。您可以將您的LongOperation課程作爲您的Activity課程的私人課程,並將TextView定義爲實例成員。在OnCreate內使用findViewById將其從佈局中取出,然後在的AsyncTask方法中修改(設置文本或其他內容)。

我希望能夠說清楚我的意思。

+0

我試圖把「TextView txtView1 =(TextView)findViewById(R.id.TextView01);」在onPostExecute方法,但即時通訊仍然得到相同的錯誤。這是你的意思嗎?你能告訴我一個你的意思嗎?在此先感謝 – robs 2011-02-12 17:49:22

5

下面是你應該做的,以使其工作,如你所願。使用onPostExecude()

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); 
    }  

} 
+0

謝謝!這幾乎做到了!但我不能得到progressdialog正常工作。我將它移到了「預執行」並顯示出來,但似乎無法將其刪除。我嘗試了onPostExecute()中的pd.hide(),但它說「pd無法解析」。繼承人代碼:[鏈接](http://paste2.org/p/1243854)在此先感謝 – robs 2011-02-12 22:12:53

+0

在構造函數中創建pd init,並在onPreExecute()中創建pd.show,並在onPostExecute()中將其刪除。並嘗試使用pd.dismiss()而不是pd.hide()。這更好。在這裏你有代碼 - > http://paste2.org/p/1244908 – Bandzio 2011-02-13 15:57:21

相關問題