我正在从服务器解析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();
}
这里检查dict的大小大于2,即
if(dict.size()&gt; 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 :(得分: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()
答案 1 :(得分:0)
您需要扩展AsyncTask或使用Handler回发到UI线程。一旦你在一个不同的线程中,你就无法进行直接改变UI的调用。