简体   繁体   中英

Android UI from other thread

I'm creating an application that gets the get the homestatus from a server in json but this happens on another thread. this isn't a problem when i try to set most Items on the ui because i can set them in a static void. but when i try to create a new switch and space i can't call 'this' to create a new.

code for getting the homestatus:

public void loadHomeStatus()
{
    if(socket != null) {`enter code here`
        if (socket.isConnected()) {
            Log.d("BtnUpdate","already connected");
            return;
        }
    }

    swAlarm = (Switch) findViewById(R.id.swAlarmState);
    tvTemperature = (TextView) findViewById(R.id.tvTemprateur);
    tvHumidity = (TextView) findViewById(R.id.tvHumidity);
    llDevices = (LinearLayout) findViewById(R.id.llDevices);

    new Thread() {
        public void run() {
            try
            {
                busyConnecting = true;
                Log.d("loadHomeStatus","trying to connect to: " + host + ":" + port);
                 socket = new Socket(host, port);
                uiConnected();

                    Log.d("loadHomeStatus","Connected");
                    DataOutputStream os = new DataOutputStream(socket.getOutputStream());
                    DataInputStream is = new DataInputStream(socket.getInputStream());


                    os.writeBytes(password);
                    Log.d("Connect", "send: " + password);
                while (socket.isConnected()) {
                    byte[] data = new byte[500];
                    int count = is.read(data);
                    String recieved = new String(data).trim();
                    Log.d("loadHomeStatus","recieved " + recieved );
                    if(recieved.toLowerCase() == "failed")
                    {
                        Log.d("loadHomeStatus","failed to log in");
                    }
                    else
                    {
                        try
                        {
                            homeStatus = new Gson().fromJson(recieved, HomeStatus.class);
                            uiLoadStatus();
                        } catch (Exception e)
                        {
                            Log.d("Error", e.toString());
                        }
                    }
                }//end of while loop

                Log.w("loadHomeStatus", "end connection thread ");
                //ends thread
                Thread.currentThread().interrupt();
                return;
            }
            catch (UnknownHostException e)
            {
                e.printStackTrace();
                Log.w("loadHomeStatus", "no Failed to connect: " + host + "-" + 8001);
            }
            catch (IOException e)
            {
                e.printStackTrace();
                Log.w("loadHomeStatus", "no Failed to connect: " + host + "-" + 8001);
            }
            Log.w("loadHomeStatus","Connection ended");
            socket = null;
            busyConnecting = false;
            uiDisconnected();
        }
    }.start();
}`

Code for setting ui

public static void uiLoadStatus()
{
    if (homeStatus != null)
    {
            try {

                tvTemperature.post(new Runnable()
                {
                    public void run()
                    {
                        //Log.d("uiLoadStatus to string",homeStatus.toString());

                        tvTemperature.setText(homeStatus.temperature + "°C");
                        tvHumidity.setText(homeStatus.humidity + "%");
                    }
                });
        }
        catch(Exception e)
        {
            Log.d("uiLoadStatus status fragment", e.toString());
        }


        try {
            swAlarm.post(new Runnable()
            {
                public void run() {
                    swAlarm.setChecked(homeStatus.alarmState);
                }
            });
        }
        catch (Exception e)
        {
            Log.d("uiLoadStatus alarm fragment", e.toString());

        }
    }
    try {
        llDevices.post(new Runnable()
        {
            public void run() {
                uiLoadDevices(); //this gives and error because it's not static
            }
        });
    }
    catch (Exception e)
    {
        Log.d("uiLoadStatus alarm fragment", e.toString());

    }
}


public void uiLoadDevices()
{
    for (int i = 0; i < homeStatus.lstDevices.size(); i++) {

        String deviceAdd = homeStatus.lstDevices.get(i);
        Space  mySpace = new Space(this);
        Switch mySwitch = new Switch(this);

        mySpace.setMinimumHeight(50);
        mySwitch.setText(homeStatus.getName(deviceAdd));
        mySwitch.setChecked(homeStatus.getState(deviceAdd));
        mySwitch.setTextSize(18);

        LinearLayout.LayoutParams lp = new          LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,       LinearLayout.LayoutParams.WRAP_CONTENT);
        lp.gravity = Gravity.LEFT;

        llDevices.addView(mySpace, lp);
        llDevices.addView(mySwitch, lp);
    }
}

uiLoadStatus is a static method (not sure why or if it has to be without looking at all of your code) and therefore you cannot call non-static methods from within it, such as uiLoadDevices

I would advise taking a look at your code and update your uiLoadStatus to not be static if at all possible. Abusing static can lead to sloppy code.

You should use AsyncTask and put the network interaction part in the doInBackground() method. To update the UI components, implement those logics in the onPostExecute() method

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM