3

I have already read many articules about this, but I can't find solution or can't implement it of my case.

I have list of buildings and when I choose element of the list the dialog is showing and other Thread is starting which connects to external database.

My problem is: I can't refresh my dialog in function run on other Thread. The text will show elements of database which is getting.

I 've tried my own Dialog class but still nothing.

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));
            }
        }
    }
};

I've tried this:

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);
}
}

And use it like

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

            testDialog.show();

but it shows nothing.

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>

Thanks for help!

rudald
  • 364
  • 5
  • 18

1 Answers1

1

For updating GUI you need to run that code on main thread or update will not be executed. Use this pattern inside your thread on places where you are updating GUI.

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

Also nice example here.

Or just use AsyncTask. Example here.

Community
  • 1
  • 1
Dejan
  • 3,046
  • 3
  • 28
  • 43
  • I don't thing that it is a good idea. To make a database access in UI thread can block the main thread, even throw a non response message. – No More Hello World Jan 09 '15 at 14:44
  • Only run on ui thread wheen you update GUI not while accessing database. Use this sample INSIDE your thread (create new runnable just to update GUI). – Dejan Jan 09 '15 at 14:45
  • or use AsyncTask which does this threading stuff for you in background. – Dejan Jan 09 '15 at 14:46
  • But he already creates a new thread. In that case, has it the same behavior as AsyncTask? – No More Hello World Jan 09 '15 at 14:49
  • Same behaviour, I just prefer runOnUiThread since i can use it many times inside one thread. – Dejan Jan 09 '15 at 14:50
  • but which solution I need to use if we're talking about Dialogs? It shows nothing I mean that I can't see the dialog not the text on dialog – rudald Jan 09 '15 at 15:19
  • Either one, both are valid. You choose what is easier for you. – Dejan Jan 09 '15 at 16:43