2016-04-14 46 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,太棒了! –