2016-04-14 51 views
0

我有一個android活動,執行異步okhttp調用時,活動加載(從onStart方法調用爲getActiveRequests())。在OkHttp的Android SetText導致崩潰的異步回調

public class MainActivity extends AppCompatActivity implements View.OnClickListener { 

Button btLogout; 
UserLocalStore userLocalStore; 
String username; 
String userEmail; 
String recentAppName; 
String recentRequestTime; 
String isExpired; 
TelephonyManager telephonyManager; 
OkHttpClient client; 
TextView tvRecentAppName, tvRecentRequestTime, tvIsExpired; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    userLocalStore = new UserLocalStore(this); 
    telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 

    TextView tvUserName = (TextView) findViewById(R.id.userName); 
    TextView tvUserEmail = (TextView) findViewById(R.id.userEmail); 

    tvRecentAppName = (TextView) findViewById(R.id.recentAppName); 
    tvRecentRequestTime = (TextView) findViewById(R.id.recentRequestTime); 
    tvIsExpired = (TextView) findViewById(R.id.isExpired); 

    client = new OkHttpClient(); 
    username = userLocalStore.getLoggedInUser().name; 
    userEmail = userLocalStore.getLoggedInUser().email; 

    tvUserEmail.setText(userEmail); 
    tvUserName.setText(username); 

    btLogout = (Button) findViewById(R.id.btLogout); 
    btLogout.setOnClickListener(this); 
} 

@Override 
protected void onStart() { 
    super.onStart(); 

    if(authenticateUser() == true){ 
     getActiveRequests(); 
    }else{ 
     startActivity(new Intent(this, LoginActivity.class)); 
    } 
} 

我想要做的就是更新一次HTTP調用已使用SetText方法所做的UI。這是我的調用,在GetActiveRequests()方法中實現。

client.newCall(request) 
      .enqueue(new Callback() { 

       @Override 
       public void onFailure(Call call, IOException e) { 
        String hello = "failed call"; 
       } 

       @Override 
       public void onResponse(Call call, Response response) throws IOException { 
        final String responseData = response.body().string(); 

        if (responseData != null) { 
         Gson gson = new Gson(); 
         JsonElement element = gson.fromJson(responseData, JsonElement.class); 
         JsonObject jsonObject = element.getAsJsonObject(); 
         final AccessRequest request = gson.fromJson(jsonObject, AccessRequest.class); 

         recentAppName = request.AppName.toString(); 
         recentRequestTime = request.RequestTime.toString(); 
         if (request.IsExpired) 
          isExpired = "Has Expired"; 
         else isExpired = "Active"; 

         tvRecentAppName.setText(recentAppName); 
         tvRecentRequestTime.setText(recentRequestTime); 
         tvIsExpired.setText(isExpired); 
        } 
       } 
      }); 

我遇到的問題是,當調試器到達SetText行代碼,它會導致應用崩潰和關閉。我不知道如何解決這個問題,但我認爲它與Okhttp Async調用不能更新UI有關,因爲我的setText方法在onCreate()中工作正常。

+0

這可能是因爲結果爲空,並且您無法將空值設置爲視圖 – Eenvincible

+0

請參閱Jake Whartons在這裏的答案http://stackoverflow.com/questions/24246783/okhttp-response-callbacks-on-the-主線程 –

+0

檢查我的[答案](http://stackoverflow.com/questions/36629346/android-settext-in-okhttp-async-callback-causing-crash/36629456#36629456)並嘗試更新UI線程上的視圖。 –

回答

1

這是因爲視圖的更新只能在UI線程上完成,OkHttp的onResponse在後臺線程上運行。嘗試在主線程上運行,像這樣:

@Override 
public void onResponse(Call call, Response response) throws IOException { 
    final String responseData = response.body().string(); 

    if (responseData != null) { 
     Gson gson = new Gson(); 
     JsonElement element = gson.fromJson(responseData, JsonElement.class); 
     JsonObject jsonObject = element.getAsJsonObject(); 
     final AccessRequest request = gson.fromJson(jsonObject, AccessRequest.class); 

     recentAppName = request.AppName.toString(); 
     recentRequestTime = request.RequestTime.toString(); 
     if (request.IsExpired) 
      isExpired = "Has Expired"; 
     else isExpired = "Active"; 

     MainActivity.this.runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       //Handle UI here       
       tvRecentAppName.setText(recentAppName); 
       tvRecentRequestTime.setText(recentRequestTime); 
       tvIsExpired.setText(isExpired);     
      } 
     }); 
    } 
} 

同樣,如果你有更新onFailure任何意見,這樣做的UI線程。

+0

謝謝你,這是爲我工作:) – jjharrison

+0

@jjharrison,太棒了! –