2011-10-17 21 views
0

我解析來自服務器的plist,並基於條件我有一個微調器顯示並從中選擇值。

這是我的代碼,實現了

public class RaconTours extends Activity implements OnClickListener { 

@Override 
    public void onCreate(Bundle savedInstanceState) { 

     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     btn = (ImageButton) findViewById(R.id.arrowBtn); 
     btn.setOnClickListener(this); 
     tourArray = new ArrayList<Tour>(); 
     btnProfile = (ImageButton) findViewById(R.id.profileBtn); 
     spinner = (Spinner) findViewById(R.id.spinner); 

     checkSDcardSupport(); 
     dialog = ProgressDialog.show(RaconTours.this, "", "Loading...", 
       true, true); 
     splashThread = new Thread() { 
      @Override 
      public void run() { 
       try { 
        /**** Specify the path of the plist file ****/ 
        File f = new File(RaconTours.PATH 
          + Constants.TOUR_MASTER_PLIST); 
        if (!f.exists()) { 
         f.createNewFile(); 
        } 
        if (f.length() <= 0) { 
         URL plistUrl = new URL(Constants.TOUR_PLIST_URL); 
         TourDescription.httpDownload(f, plistUrl); 
        } 
       } catch (MalformedURLException mue) { 
        mue.printStackTrace(); 
       } catch (IOException ioe) { 
        ioe.printStackTrace(); 
       } 
       /**** Call the method to parse the downloaded plist file ****/ 
       parsePlist(); 
       if(dialog!=null){ 
        dialog.dismiss(); 
       } 
      } 
     }; 
     splashThread.start(); 



    } 

現在parsePlist方法中,

public void parsePlist() { 


      try { 
       /**** Opens and reads the downloaded file ****/ 

       InputStream is = new BufferedInputStream(new FileInputStream(
         RaconTours.PATH + Constants.TOUR_MASTER_PLIST)); 
       XMLPropertyListConfiguration plist = new XMLPropertyListConfiguration(
         is); 

       HashMap<String, Object> dict = plist.mPlistHashMap; 
       // check if more than 1 city exists, if they exist display a spinner to select the city 
       if (dict.size() > 2) { 
        try { 
        spinner.setVisibility(View.VISIBLE); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
        //dict.remove("venueicons"); 
        for (Object objSpinner: dict.keySet()) { 
         spin = (String) objSpinner.toString(); 
         // add the keys to the string array list 
         spinnerKeys.add(spin); 
        } 
        // set the array list as the data for the adapter 
        ArrayAdapter<String> spinnerData=new ArrayAdapter<String>(this, 
          android.R.layout.simple_spinner_item, 
          spinnerKeys); 

        spinnerData.setDropDownViewResource(
          android.R.layout.simple_spinner_dropdown_item); 
         spinner.setAdapter(spinnerData); 

        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 
         public void onItemSelected(AdapterView<?> parent, 
           View view, int pos, long id) { 
          Object item = parent.getItemAtPosition(pos); 
          city = item.toString(); 
         } 

         public void onNothingSelected(AdapterView<?> parent) { 
          Toast.makeText(getApplicationContext(), "Please select a city", Toast.LENGTH_SHORT).show(); 
         } 
        }); 

       } 
       for (Object key : dict.keySet()) { 

        if (key.toString().equals("venueicons")) { 
         continue; 
        } 
        city = key.toString(); 

        HashMap<String, Object> cityDict = (HashMap<String, Object>) dict 
          .get(city); 
        for (Object cityKey : cityDict.keySet()) { 

         tour = new Tour(); 
    ..... 
      } 
    } 
catch (FileNotFoundException fnfe) { 
    fnfe.printStackTrace(); 
} 

我在這裏檢查字典的大小大於2,即

如果(字典.size()> 2){ ...

}

在此基礎上,我做了微調可見的,但它給我的

10-17 08:24:33.240: WARN/System.err(4538): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 
10-17 08:24:33.250: WARN/System.err(4538):  at android.view.ViewRoot.checkThread(ViewRoot.java:2932) 
10-17 08:24:33.250: WARN/System.err(4538):  at android.view.ViewRoot.focusableViewAvailable(ViewRoot.java:1712) 
10-17 08:24:33.260: WARN/System.err(4538):  at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:452) 
10-17 08:24:33.270: WARN/System.err(4538):  at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:452) 
10-17 08:24:33.270: WARN/System.err(4538):  at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:452) 
10-17 08:24:33.290: WARN/System.err(4538):  at android.view.View.setFlags(View.java:4633) 
10-17 08:24:33.290: WARN/System.err(4538):  at android.view.View.setVisibility(View.java:3116) 
10-17 08:24:33.290: WARN/System.err(4538):  at com.racontrs.Racontours.RaconTours.parsePlist(RaconTours.java:157) 
10-17 08:24:33.300: WARN/System.err(4538):  at com.racontrs.Racontours.RaconTours$1.run(RaconTours.java:85) 

爲線

spinner.setVisibility(View.VISIBLE);

對此的任何回答?

回答

0

你的splashThread運行在它自己的線程上(而不是UI線程),這意味着對parseList的調用也會在非UI線程上運行,導致UI更改爲「非法」操作。

您應該看看AsyncTask - 它可能有更好的用途,因爲它具有在UI線程上運行以進行UI更改的方法。

的AsyncTask,例如

用以下內容替換你的方法parsePList()

private class PListParser extends AsyncTask<Void, Void, Boolean> { 
    public Boolean doInBackground(Void... params) { 
    //do the things your method parsePList does here. 

    if(dict.size() > 2) 
     return true; 
    else 
     return false; 
    } 

    public void onPostExecute(Boolean result) { 
    //result is the return-value of the doInBackground-method 
    if(result) 
     spinner.setVisibility(View.VISIBLE); 
    else 
     spinner.setVisibility(View.GONE); 
    } 
} 

然後,而不是調用parsePList()你這樣做:new PListParser().execute()

+0

你能給我一些額外的信息嗎?我的意思是細節 – tejas

0

您需要延長的AsyncTask或使用處理程序回發到UI線程。一旦你在不同的線程中,你不能直接調用UI來調用。

相關問題