2016-04-14 10 views
0

Ich habe eine android Aktivität, die eine Asynchronous Okhttp Anruf ausführt, wenn die Aktivität geladen wird (so genannte von der onStart Verfahren nach getActiveRequests()).Android SetText in OkHttp Async Rückruf verursachen crash

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)); 
    } 
} 

Was ich tun möchte, ist Update der Benutzeroberfläche, wenn der HTTP-Aufruf der SetText Methoden hergestellt wurde mit. Hier ist mein Aufruf, implementiert in der GetActiveRequests() -Methode.

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); 
        } 
       } 
      }); 

Das Problem, das ich habe ist, dass, wenn der Debugger die SetText Codezeilen erreicht, ist es die App zum Absturz zu bringen und in der Nähe verursacht. Ich bin ratlos, wie ich das lösen kann, aber ich nehme an, es hat etwas mit dem Okhttp Async Aufruf nicht in der Lage, die Benutzeroberfläche zu aktualisieren, da meine SetText-Methoden in onCreate() gut funktionieren.

+0

Es ist wahrscheinlich, weil das Ergebnis null ist und Sie keinen Nullwert auf eine Ansicht – Eenvincible

+0

setzen können Siehe Jake Whartons Antwort hier, http://stackoverflow.com/questions/24246783/okhttp-response-callbacks-on-the- main-thread –

+0

Überprüfen Sie meine [Antwort] (http://stackoverflow.com/questions/36629346/android-settext-in-ochttp-async-callback-causing-crash/36629456#36629456) und versuchen Sie, Ansichten auf UI-Thread zu aktualisieren . –

Antwort

1

Das liegt daran, dass Ansichten Updates nur auf UI-Thread und OkHttp onResponse läuft im Hintergrund Thread durchgeführt werden kann. Versuchen Sie das mal auf Haupt-Thread wie dies auszuführen:

@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);     
      } 
     }); 
    } 
} 

Ähnlich, wenn Sie irgendwelche Ansichten über onFailure aktualisieren, tun es auf UI-Thread.

+0

danke, das funktioniert für mich :) – jjharrison

+0

@jjharrison, großartig! –