簡體   English   中英

Android服務線程發出Web請求阻止了UI

[英]Android service thread making web request is blocking UI

首先,我將解釋當前的情況。 我在2個服務中有2個不同的線程(從USB端口服務讀取並進行Web請求服務)。 我在我的活動的onCreate中啟動它們,例如:

serialServiceIntent = new Intent(NDKSerialActivity.this, SerialService.class);
startService(serialServiceIntent);
webServiceIntent = new Intent(NDKSerialActivity.this, RecordWebService.class);
startService(webServiceIntent);

串行服務沒有什么問題,但是在RecordWebService中,當我發出請求時,gui會停止,直到響應到來為止。

代碼是這樣的:

public class RecordWebService extends Service
{
public static final String SERVER_ADDRESS = "http://192.168.1.100:8080/MobilHM/rest";
private static final String TAG = RecordWebService.class.getSimpleName();
private RecordWebThread recordWebThread;

@Override
public void onStart(Intent intent, int startId)
{
    super.onStart(intent, startId);
    recordWebThread = new RecordWebThread(true);
    recordWebThread.start();
}

@Override
public void onDestroy()
{
    super.onDestroy();
    Log.i(TAG, "RecordWebService Destroyed");
}

@Override
public IBinder onBind(Intent intent)
{
    return null;
}
}

public class RecordWebThread extends Thread
{
private static final String TAG = RecordWebThread.class.getSimpleName();
public boolean always;


public RecordWebThread(boolean always)
{
    this.always = always;
}

@Override
public void run()
{
    PatientRecord patientRecord = new PatientRecord();
    while (always)
    {
        RestClient restClient = new RestClient(RecordWebService.SERVER_ADDRESS + "/hello");
        try
        {
            restClient.execute(RequestMethod.GET);
        }
        catch (Exception e1)
        {
            Log.e(TAG, "", e1);
        }
        Log.i(TAG, "Server Response Code:->" + restClient.getResponseCode());
        Log.i(TAG, "Server Response:->" + restClient.getResponse());
        try
        {
            sleep(4 * 1000);
        }
        catch (InterruptedException e)
        {
            Log.e(TAG, "Web service interrupted", e);
        }
    }
}
}

我也嘗試刪除睡眠部分並使線程與計時器和計時器任務一起運行,例如:

public void sendRecord()
{
    scanTask = new TimerTask()
    {
        public void run()
        {
            handler.post(new Runnable()
            {
                public void run()
                {
                    RestClient restClient = new RestClient(RecordWebService.SERVER_ADDRESS + "/hello");
                    try
                    {
                        restClient.execute(RequestMethod.GET);
                    }
                    catch (Exception e1)
                    {
                        Log.e(TAG, "", e1);
                    }
                    Log.i(TAG, "Server Response Code:->" + restClient.getResponseCode());
                    Log.i(TAG, "Server Response:->" + restClient.getResponse());
                }
            });
        }
    };
    t.schedule(scanTask, 1000, 4000);
}

但沒有運氣,當談到restClient.execute時,我的gui掛起了。

您可以在http://www.giantflyingsaucer.com/blog/?p=1462上找到RestClient.java

如何使我的請求不阻止我的GUI線程?

編輯:

public void sendRecord()
{
    scanTask = new TimerTask()
    {
        public void run()
        {
            RestClient restClient = new RestClient(RecordWebService.SERVER_ADDRESS + "/hello");
            try
            {
                restClient.execute(RequestMethod.GET);
            }
            catch (Exception e1)
            {
                Log.e(TAG, "", e1);
            }
            Log.i(TAG, "Server Response Code:->" + restClient.getResponseCode());
            Log.i(TAG, "Server Response:->" + restClient.getResponse());
        }
    };
    t.schedule(scanTask, 1000, 4000);
}

沒有處理程序,我在我的活動的onCreate中調用此方法,但仍然ui掛起。

或者,您可以使用IntentService來為您處理線程問題。

這是一個示例類:

public class MyService extends IntentService {

    public MyService() {
        super("MyService");
    }

    public MyService(String name) {
        super(name);        
    }

    @Override
    protected void onHandleIntent(Intent arg0) {

                //Do what you want
        }
}

然后,您只需致電:

Intent intent = new Intent(getApplicationContext(),MyService.class);
startService(intent);

編輯:

要每4秒重復一次相同的操作,您應該執行以下操作:

 PendingIntent serviceIntent= PendingIntent.getService(context,
                0, new Intent(context, MyService.class), 0);

   long firstTime = SystemClock.elapsedRealtime();
   AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);

   long intervalInSec = 4;

   am.setRepeating(AlarmManager.ELAPSED_REALTIME, firstTime, intervalInSec*1000, serviceIntent)

;

接下來是代碼(二維版本):創建線程,並要求UI線程進行一些網絡交互。 只是在執行請求時排除handler.post(...) 稍后,您可以將其用於簡單的可運行狀態,以使用請求結果更新UI。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM