安卓提示对话框及文本刷新

3

我已经阅读了很多关于这个问题的文章,但是我无法找到解决方法或者不能将其应用到我的情况中。

我有一个建筑物列表,当我选择列表元素时,会显示对话框并启动另一个线程连接外部数据库。

我的问题是: 在其他线程的run函数中,我无法刷新我的对话框。文本将显示从数据库中获取的元素。

我尝试使用自己的对话框类,但仍然没有效果。

public class BuildingListActivity extends ListActivity {

private WifiManager wifiManager;
static String[] buildingsName = null;
SqLiteDatabaseCRUD database;
List<Budynek> budynkiExternal =  new ArrayList<Budynek>();;
List<Budynek> budynkiInternal =  new ArrayList<Budynek>();;
CustomArrayAdapter adapter;
AlertDialog alertDialog;
TextView dialogText;
ListView listView;
View v;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_building_list);
    v = getLayoutInflater().inflate(R.layout.dialog, null);
    dialogText = (TextView)v.findViewById(R.id.textView);
    listView = (ListView)findViewById(android.R.id.list);

    ...


    getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view,
                                int position, long id) {


            alertDialog = new AlertDialog.Builder(BuildingListActivity.this).create();
            alertDialog.setTitle("Alert Dialog");
            alertDialog.setMessage("Welcome to AndroidHive.info");


            alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    // Write your code here to execute after dialog closed
                    Toast.makeText(getApplicationContext(), "You clicked on OK", Toast.LENGTH_SHORT).show();
                }
            });
            alertDialog.show();

            Thread getData = new Thread(getDatas, "external_database");
            getData.start();
        }

    });
}

private Runnable getDatas = new Runnable()
{
    @Override
    public void run()
    {
        SqLiteDatabaseCRUD database = new SqLiteDatabaseCRUD(getApplicationContext());
        List<Integer> idList = new ArrayList<Integer>();
        idList = adapter.getIdList();
        ExternalDatabase externalConnection = new ExternalDatabase();

        List<Pomieszczenie> pomieszczenieList;
        List<DaneSurowe> daneList;
        List<AP> routerList;
        for(int i = 0; i < idList.size(); i++)
        {
            database.createFieldBudynek(externalConnection.getBudynek(idList.get(i)));
            pomieszczenieList = externalConnection.getPomieszczenieByBudynek(idList.get(i));
            daneList = externalConnection.getDaneSurowe(idList.get(i));
            routerList = externalConnection.getAPbyPomieszczenie(idList.get(i));

            for(int j = 0; j < pomieszczenieList.size(); j++)
            {
                database.createFieldPomieszczenie(pomieszczenieList.get(j));
            }
            for(int j = 0; j < daneList.size(); j++)
            {
                database.createFieldDaneSurowe(daneList.get(j));
            }
            for(int j = 0; j < routerList.size(); j++)
            {
                database.createFieldAP(routerList.get(j));
            }
        }
    }
};

我已经尝试过这个方法:
public class DatabaseDialog extends Dialog {
View v = null;

public DatabaseDialog(Context context) {
    super(context);
}

public Dialog show(Context context) {
    Dialog d = new Dialog(context);
    v = LayoutInflater.from(context).inflate(R.layout.dialog, null);
    d.setContentView(v);
    return d;
}

public void update() {
    v.invalidate();
  //  v.setId(R.id.textView);
}
}

并像这样使用它

            Dialog testDialog = new Dialog(getApplicationContext());
            DatabaseDialog dialog = new DatabaseDialog(getApplicationContext());
            testDialog =  dialog.show(getApplicationContext());

            testDialog.show();

但是它什么也没有显示。

dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:text="Medium Text"
    android:id="@+id/textView"
    android:layout_gravity="center_horizontal" />
</LinearLayout>



activity_building_list
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.example.arkadio.naviwifi.BuildingListActivity">
<ListView
    android:id="@android:id/list"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" />
</RelativeLayout>

感谢您的帮助!
1个回答

1

要更新GUI,您需要在主线程上运行该代码,否则更新将不会执行。在更新GUI的位置内部,在您的线程中使用此模式。

activity.runOnUiThread(
    new Runnable(){
       @Override
       public void run(){
           // HERE UPDATE GUI
       }
    }
);

您可以在这里找到一个很好的编程示例 这里

或者只需使用AsyncTask。 示例 这里


我认为这不是一个好主意。在UI线程中进行数据库访问可能会阻塞主线程,甚至会导致无响应消息。 - No More Hello World
只有在更新GUI时才在UI线程上运行,而不是在访问数据库时。在您的线程中使用此示例(创建新的可运行对象来更新GUI)。 - Dejan
或者使用AsyncTask,在后台为您执行这些线程操作。 - Dejan
但他已经创建了一个新的线程。在这种情况下,它是否具有与AsyncTask相同的行为? - No More Hello World
任意一个都可以,两个都有效。你选择哪个对你来说更容易。 - Dejan
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接