我有一个问题。我有一个主类(MyActivity),用户在其中从微调器中选择一个位置。当用户选择一个项目时,这应该触发一个Async方法,然后以测量的形式返回数据(包括temp,winddirection等)。
我得到了微调器和异步任务,以便他们应该启动。我的问题是,我应该如何获得测量结果,以便我可以在MyActivity中读取它并将数据放在som TextViews中。我试过的一件事是使用Async任务中的方法setTextView(onPostExecute),但后来我得到了一个Null异常,认为TextView还没有设置。
MyActivity代码:
public class MyActivity extends Activity {
//Activity which basicly is the GUI. The user can click the menu button to configure widgets from here.
//TODO: Daniel add some fancy wind graphs
TextView txt_spotName;
TextView txt_spotTemp;
TextView txt_spotWind;
Measurement measurement2;
public Boolean b;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt_spotName = (TextView) findViewById(R.id.txt_spotName);
txt_spotTemp = (TextView) findViewById(R.id.txt_spotTemp);
txt_spotWind = (TextView) findViewById(R.id.txt_spotWindDir);
final Spinner spotChooser = (Spinner) findViewById(R.id.spin_spotvelger);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.spots, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spotChooser.setAdapter(adapter);
spotChooser.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int pos, long l) {
//User selected a value in the spinner
//String s = String.valueOf(pos);
String spotName = (String) spotChooser.getItemAtPosition(pos);
Spots spots = new Spots();
spotName = spots.getSpotIdFromName(spotName);
//spotName now equals the ID instead of the Name
//Call the updateNow function with the ID and a debug parameter.
VindsidenUpdateService vindsidenUpdateService = new VindsidenUpdateService();
vindsidenUpdateService.updateNow(spotName, "user");
//Here the code shoud somehow wait untill "measurement2" is set by the Async task.
//My biggest issue that i dont know how to do this code right.
try {
txt_spotName.setText(measurement2.getStationID());
} catch (Exception e) {
}
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
public void setTextView (String s ){
//This should in theory work but i cant get it to setText.
//The error i get is basicly that "txt_spotname" = null
txt_spotName.setText(s);
}
//OnOptionsItemSelected is called when user clicks the menu/overflow button
@Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
//Switch case to check which menu item user clicked
switch (menuItem.getItemId()) {
case R.id.settings:
//Define settings page to be com.vindsiden.windwidget/.Settings
String SettingsPage = "com.vindsiden.windwidget/.Settings";
try {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(ComponentName.unflattenFromString(SettingsPage));
intent.addCategory(Intent.CATEGORY_LAUNCHER);
startActivity(intent);
} catch (ActivityNotFoundException e)
{
//This will be called when activity is not found (Check manifest)
Log.d("", e.getStackTrace().toString());
}
break;
case R.id.About:
About.Show(this);
//TODO : Add featurerequest/send email to developer
//http://stackoverflow.com/questions/2197741/how-to-send-email-from-my-android-application
}
return true;
}
}
异步类代码:
public class VindsidenUpdateService {
private static final String NEXT_SCHEDULE_URI_POSTFIX = "/next_schedule";
private static final String WIDGET_URI_PREFIX = "/widget_id/";
List<Measurement> measurements = null;
public void updateNow(String stationID, String from) {
//upDateNow is just used to call the GetData method
//stationID = "1";
try {
if (stationID.equals("")) {
//Actually used for debugging
stationID = "1";
}
//Start the GetData
String[] input = {String.valueOf(stationID), from};
new GetData().execute(input);
} catch (Exception e) {
Log.d("Vindsiden2" + " UpdateNow", "Failed");
}
}
class GetData extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... data) {
String s = data.toString();
Log.d("Vindsiden2 + Convert array to string", s);
try {
String urlString = WindWidgetConfig.getVindsidenUrlPrefix() + data[0].toString()
+ WindWidgetConfig.getVindsidenUrlPostfix();
Log.d("Vindsiden2", urlString);
measurements = (new VindsidenWebXmlReader()).loadXmlFromNetwork(urlString);
Log.d("Vindsiden2", measurements.toString());
//Filldata here
} catch (IOException e) {
Log.d("Vindsiden2", "An IO exception occured. Stack follows: ");
Log.d("Vindsiden2", e.getStackTrace().toString());
// xmlRetrievalSuccessful = false;
// not certain how robust throwing a runtime exception is, might break stuff with recurrence etc!
// throw new RuntimeException(getResources().getString(R.string.connection_error));
} catch (XmlPullParserException e) {
Log.d("Vindsiden", "An XmlPullParserException occured. Stack follows: ");
Log.d("Vindsiden", e.getStackTrace().toString());
//xmlRetrievalSuccessful = false;
// throw new RuntimeException(getResources().getString(R.string.xml_error));
}
Log.d("Vindsiden ", "Got data, now find measurment");
String Return = "";
int array = data.length;
if (array == 1) {
//stop
Return = "";
} else if (array == 2) {
Return = data[1].toString();
}
return Return;
}
protected void onPostExecute(String result) {
// fillData(measurements);
MyActivity myActivity = new MyActivity();
myActivity.measurement2 = measurements.get(0);
//ive also tried to create a setTextView method in MyActivity but this dosent seem to work either.
//Commect
}
}
}
完整代码可在以下网址找到:https://github.com/danielgolan/Vindsiden/tree/Daniel2