Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding a view from background thread

I am attempting to add multiple textviews to an already inflated layout. The information displayed is being pulled from a database, with one textview created for each row in the database. Since the database can be extremely large, I create each textview one at a time in a background thread, and add it to the foreground.

Here is the function called in the background thread to update the foreground:

private TextView temp;
private void addClickableEvent(ReviewHistoryEvent e){
    if(e == null){
        Log.e(tag,"Attempted to add a null event to review history");
        return;
    }
    TextView t = new TextView(getBaseContext());
    t.setTag(e);
    t.setText(e.getTime()+"  "+e.getEvent());
    t.setClickable(true);
    t.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    t.setTextAppearance(getBaseContext(), R.style.Information_RegularText);
    t.setGravity(Gravity.CENTER);
    t.setOnClickListener(this);

    temp = t;
    runOnUiThread(new Runnable() {
         public void run() {
             LinearLayout display = (LinearLayout) findViewById(R.id.reviewHistory_display);
            display.addView(temp);
        }
    });
}

This function runs once successfully and the first textview appears. However, when it is called a second time, it fails on the display.addView(temp); line with the following error:

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the childs's parent first.

I am unsure why my textview already has a parent if it is supposedly newly instantiated. Also I use the temp textview to get around my runnable not being able to reference the local textview t. Is this correct? Any help would be appreciated.

like image 806
jsjrobotics Avatar asked Oct 06 '22 01:10

jsjrobotics


1 Answers

Instead of using a member variable (which can be modified and which is not local, of course), use a final TextView instead:

final TextView t = new TextView(getBaseContext());
// ...

temp = t; // Remove this
runOnUiThread(new Runnable() {
     public void run() {
        // ...
        display.addView(t);
    }
});
like image 185
Cat Avatar answered Oct 10 '22 03:10

Cat