如何更新textview不是从主线程?

时间:2015-08-25 12:03:12

标签: android aidl

我有两个应用程序,一个是服务,一个是客户端 客户端通过AIDL连接到服务应用程序。 当客户端从服务接收数据时我希望它在textView中显示它,但是我无法更新textView,我收到以下错误:

*** Uncaught remote exception!  (Exceptions are not yet supported across processes.)
    android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
            at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4039)
            at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:709)
            at android.view.View.requestLayout(View.java:12675)
            at android.view.View.requestLayout(View.java:12675)
            at android.view.View.requestLayout(View.java:12675)
            at android.view.View.requestLayout(View.java:12675)
            at android.view.View.requestLayout(View.java:12675)
            at android.view.View.requestLayout(View.java:12675)
            at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:268)
            at android.view.View.requestLayout(View.java:12675)
            at android.widget.TextView.checkForRelayout(TextView.java:6773)
            at android.widget.TextView.setText(TextView.java:3306)
            at android.widget.TextView.setText(TextView.java:3162)
            at android.widget.TextView.setText(TextView.java:3137)
            at com.tfl.tfltemperatureapplication.MainActivity.DisplayTemp(MainActivity.java:139)
            at com.tfl.tfltemperatureapplication.MainActivity$1.onSuccess(MainActivity.java:84)
            at com.tfl.extprotocolservice.IParameterCallBack$Stub.onTransact(IParameterCallBack.java:54)
            at android.os.Binder.execTransact(Binder.java:338)
            at dalvik.system.NativeStart.run(Native Method)

我的客户代码:

public class MainActivity extends ActionBarActivity implements ServiceConnection {
    double temperature;
    TextView frontTemp,rearTemp;
    private IParameter binding=null;
    public static final int FRONT_TEMPERATURE_PARAMETER=262;
    public static final int REAR_TEMPERATURE_PARAMETER=263;

    public static final String TAG="TEMPERATURE";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(activity_main);
        frontTemp= (TextView) findViewById(R.id.front_temp);
        rearTemp= (TextView) findViewById(R.id.rear_temp);
        connectToService();
    }

    public void connectToService() {
        Intent implicit = new Intent(IParameter.class.getName());
        List<ResolveInfo> matches = getPackageManager().queryIntentServices(implicit, 0);
        if (matches.size() == 0) {
            Toast.makeText(getApplicationContext(), "Cannot find a matching service!", Toast.LENGTH_LONG).show();
        } else if (matches.size() > 1) {
            Toast.makeText(getApplicationContext(), "Found multiple matching services!", Toast.LENGTH_LONG).show();
        } else {

            Intent explicit = new Intent(implicit);
            ServiceInfo svcInfo = matches.get(0).serviceInfo;
            ComponentName cn = new ComponentName(svcInfo.applicationInfo.packageName, svcInfo.name);
            explicit.setComponent(cn);
            ComponentName myService=startService(new Intent(this,IParameter.class));
            bindService(explicit, this, Context.BIND_AUTO_CREATE);


        }
    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        Log.d(TAG, "Connected to service");
        Thread t1=new Thread(new BindingToService(service));
        t1.start();


    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        binding=null;

    }
    IParameterCallBack.Stub cb=new IParameterCallBack.Stub(){



        @Override
        public void onSuccess(int parameter, int value) throws RemoteException {
            temperature=ConvertToCelcius(value);
            DisplayTemp(parameter,temperature);

        }

        @Override
        public void onFailure(String msg) throws RemoteException {
            Log.d(TAG,"Failed to receive parameter: "+msg );

        }
    };

    public class BindingToService implements Runnable{
        IBinder service;
        public BindingToService(IBinder service){
            this.service=service;
        }

        @Override
        public void run() {
            binding=IParameter.Stub.asInterface(service);
            while(true){
                try {
                    binding.askForParameter(FRONT_TEMPERATURE_PARAMETER,cb);
                } catch (RemoteException e) {
                    Log.e(TAG, "" + e);
                }
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                try {
                    binding.askForParameter(REAR_TEMPERATURE_PARAMETER, cb);
                } catch (RemoteException e) {
                    Log.e(TAG, "" + e);
                }
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }

        }
    }
    public static double ConvertToCelcius(int temperature){
        return (double)temperature*0.00390625-273;
    }

    public void DisplayTemp(int parameter,double temperature){
        if(parameter==262){
            frontTemp.setText(""+temperature);
        }
        if(parameter==263){
            rearTemp.setText(""+temperature);
        }
    }

1 个答案:

答案 0 :(得分:1)

你可以使用

runOnUiThread(new Runnable() {
        @Override
        public void run() {
            //do your UI related operation
        }
    });