我想在我的activity_main.xml ScrollView中生成一个表单。 XML正确加载和解析,但是当我尝试添加View(LinearLayout)时,它会抛出异常e。我的应用程序通过推送通知获取XML文件的URL,然后解析它。根据XML,它应该生成一个表单并将其显示给用户。我以此为例:https://www.ibm.com/developerworks/xml/tutorials/x-andddyntut/#l1
这是我的主要活动:
public class MainActivity extends Activity {
// label to display gcm messages
TextView lblMessage;
Controller aController;
public ScrollView sv;
Button execute;
// Asyntask
AsyncTask<Void, Void, Void> mRegisterTask;
public static String name;
public static String email;
final Context context = this;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ScrollView sv = (ScrollView) findViewById(R.id.sv);
...
}
// Create a broadcast receiver to get message and show on screen
private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String newMessage = intent.getExtras().getString(Config.EXTRA_MESSAGE);
// Waking up mobile if it is sleeping
aController.acquireWakeLock(getApplicationContext());
ScrollView sv = (ScrollView) findViewById(R.id.sv);
new DoInBackground(getApplicationContext(), sv).execute(newMessage);
// Releasing wake lock
aController.releaseWakeLock();
}
};
这是我的异步类:
public class DoInBackground extends AsyncTask<String, Void, Void> {
Context mContext;
ScrollView mSv;
String tag = "DynamicFormXML";
XmlGuiForm theForm;
ProgressDialog progressDialog;
Handler progressHandler;
public DoInBackground(Context context, ScrollView sv) {
this.mContext = context;
this.mSv = sv;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(String... params) {
if (GetFormData(params[0])) {
DisplayForm();
}
else
{
Log.e(tag,"Couldn't parse the Form.");
AlertDialog.Builder bd = new AlertDialog.Builder(mContext);
AlertDialog ad = bd.create();
ad.setTitle("Error");
ad.setMessage("Could not parse the Form data");
ad.show();
}
return null;
}
protected void onPostExecute() {
}
private boolean DisplayForm()
{
try
{
final LinearLayout ll = new LinearLayout(mContext);
mSv.addView(ll); //Here it fails
ll.setOrientation(android.widget.LinearLayout.VERTICAL);
...
} catch (Exception e) { // Goes to here
Log.e(tag,"Error Displaying Form");
return false;
}
}
我认为主要活动的上下文以及主要活动中的空Scrollview都是正确转发的(它们不是空的)但我不是100%肯定。任何帮助/提示表示赞赏! :)
答案 0 :(得分:1)
您无法从后台线程(例如运行doInBackground
方法的线程)触摸GUI。
在AsynTask
中,您可以将UI代码放在onPostExecute中,在UI线程上调用,结果为doInBackground
。
如果您有中间结果,可以从doInBackground
调用publishProgress,这将触发在UI线程上调用onProgressUpdate,您可以在其中更新UI。
有关示例以及有关在哪个线程上必须执行的操作的更多详细信息,请参阅AsyncTask API 。
答案 1 :(得分:0)
<强>解决方案强>
重新排序代码(因此GUI内容将在onPostExecute上完成)有效。我还有一个问题,没有得到onPostExecute()但我不得不将其更改为onPostExecute(Void结果)。
现在我的代码看起来像这样,就像一个魅力:
public class DoInBackground extends AsyncTask<String, Void, Void> {
Context mContext;
LinearLayout mLl;
String tag = "DynamicFormXML";
XmlGuiForm theForm;
ProgressDialog progressDialog;
Handler progressHandler;
public DoInBackground(Context context, LinearLayout ll) {
this.mContext = context;
this.mLl = ll;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(String... params) {
getFormData(params[0]);
return null;
}
protected void onPostExecute(Void result) {
DisplayForm();
}
我还将ScrollView和LinearLayout添加到我的activity_main.xml中,因此DisplayForm()看起来就像那样(如果你想按照我之前提到的例子):
private void DisplayForm() {
try
{
// walk thru our form elements and dynamically create them, leveraging our mini library of tools.
int i;
for (i=0;i<theForm.fields.size();i++) {
if (theForm.fields.elementAt(i).getType().equals("text")) {
theForm.fields.elementAt(i).obj = new XmlGuiEditBox(mContext,(theForm.fields.elementAt(i).isRequired() ? "*" : "") + theForm.fields.elementAt(i).getLabel(),"");
mLl.addView((View) theForm.fields.elementAt(i).obj);
}
...