2017-04-25 11 views
0

webservice에서 일부 문자열을 가져 오는 작업자 스레드 내에서 runOnUiThread를 사용하여 UI의 TextView를 업데이트해야합니다. 나는 다른 게시물을 여기에서 보았고 제공되는 솔루션을 구현하려했지만 내 앱을 시작할 때 충돌이 발생했다. 이 방법에 너무 익숙하지 않아서이 문제를 해결하는 방법에 대한 지침이 필요합니다.runOnUiThread Android를 올바르게 구현하는 방법

04-2512 : 19 : 59.917 4108-4108 /? I/art : 늦지 않게 -Xcheck : jni (이미 켜짐) 04-25 12 : 19 : 59.917 4108-4108 /? W/art : 기본값을 사용하는 X86 용 예상치 못한 CPU 변형 : x86 04-25 12 : 20 : 00.147 4108-4108/com.example.gmars.parseltonguev2 W/System : 알 수없는 경로로 참조 된 ClassLoader : /data/app/com.example .gmars.parseltonguev2-2/lib/x86 04-25 12 : 20 : 00.154 4108-4108/com.example.gmars.parseltonguev2 I/InstantRun : 인스턴트 런 서버 시작 : 주 프로세스 04-25 12:20 : 00.218 4108-4108/com.example.gmars.parseltonguev2 D/AndroidRuntime : 종료 VM 04-25 12 : 20 : 00.218 4108-4108/com.example.gmars.parseltonguev2 E/AndroidRuntime : 치명적인 예외 : 주 프로세스 : com.example.gmars.parseltonguev2, PID : 4108 java.lang.RuntimeException : 활동을 인스턴스화 할 수 없습니다. ComponentInfo {com.example.gmars.parseltonguev2/com.example.gmars.parseltonguev2.MainActivity} : java.lang.NullPointer 예외 : android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2548)의 null 객체 참조 에서 가상 메소드 'android.view.Window $ Callback android.view.Window.getCallback()'을 (를) 호출하려고 시도했습니다. android.page에서 . android.os에서 android.app.ActivityThread $ H.handleMessage (ActivityThread.java:1460) 에서 android.app.ActivityThread.-wrap12 (ActivityThread.java) 에서 app.ActivityThread.handleLaunchActivity (ActivityThread.java:2707) .Handler.dispatchMessage (Handler.java:102) android.os.Looper.loop (Looper.java:154)의 android.app.ActivityThread.main (ActivityThread.java:6077) (네이티브 메소드) com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:865) at com.android.internal.os.ZygoteInit.main (java.lang.reflect.Method.invoke) ZygoteInit.java:755) 에 의해 발생 : java.lang.NullPointerException : android.support에서 null 객체 참조 에 가상 메소드 'android.view.Window $ Callback android.view.Window.getCallback()'을 호출하려고 시도했습니다. v7.app.AppCompatDelegateImplBase. android.support.v7.app.AppCompatDelegateImplV9에서 (AppCompatDelegateImplBase.java:120) . (AppCompatDelegateImplV9.java:155) android.support.v7.app.AppCompatDelegateImplV11시. (AppCompatDelegateImplV11.java:31) android.support.v7.app.AppCompatDelegateImplV14시. (AppCompatDelegateImplV14.java:55) android.support.v7.app.AppCompatDelegateImplV23에서 . (AppCompatDelegateImplV23.java:33) android.support.v7.app.AppCompatDelegateImplN시. (AppCompatDelegateImplN.java:33) 안드로이드에서 android.support.v7.app.AppCompatDelegate.create (AppCompatDelegate.java:185에서 android.support.v7.app.AppCompatDelegate.create (AppCompatDelegate.java:201) 에서 ) . support.v7.app.AppCompatActivity.getDelegate (AppCompatActivity.java:519) android.support.v7.app.AppCompatActivity.findViewById (AppCompatActivity.java:190) at com.example.gmars.parseltonguev2.MainActivit y (MainActivity.java:30) at java.lang.Class.newInstance (기본 메소드) android.app에 있습니다.Instrumentation.newActivity (Instrumentation.java:1078) android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2538)에서 android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2707)에서 android.app.ActivityThread에서 . -wrap12 (ActivityThread.java) android.app.ActivityThread $ H.handleMessage (ActivityThread.java:1460) at android.os.Handler.dispatchMessage (Handler.java:102) at android.os.Looper.loop (Looper.java:154) android.app.ActivityThread.main (ActivityThread.java:6077) at java.lang.reflect.Method.invoke (기본 메소드)com.android.internal.os.ZygoteInit.main에서 com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:865) 에서 17,451,515,(ZygoteInit.java:755)

Activity updateUI; 

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

    updateUI = this; 

    itemList = new ArrayList<>(); 

    new GetItemAvailability().execute(); 

} 

@Override 
    public Void doInBackground(Void... arg0) { 
     HttpHandler handler = new HttpHandler(); 

     String JSON_DATA = handler.makeServiceCall(url); 

     Log.e(TAG, "Response from url: " + JSON_DATA); 

     if (JSON_DATA != null) { 
      JSON_DATA = JSON_DATA.substring(JSON_DATA.indexOf('{'),JSON_DATA.lastIndexOf('}')+1); 
      Log.e(TAG, "Substring of response: " + JSON_DATA); 
      try { 
       JSONObject reader = new JSONObject(JSON_DATA); 

       JSONObject availability = reader.getJSONObject("availability"); 

       final String availableQuantity = availability.getString("availableQuantity"); 
       final String defaultBranch = availability.getString("defaultBranch"); 
       final String defaultInventoryBranch = availability.getString("defaultInventoryBranch"); 
       final String inventoryBranch = availability.getString("inventoryBranch"); 
       final String footage = availability.getString("footage"); 
       final String anticipatedStockDate = availability.getString("anticipatedStockDate"); 
       final String discontinuedItemFlag = availability.getString("discontinuedItemFlag"); 
       final String mdc = availability.getString("mdc"); 
       final String mdcquantity = availability.getString("mdcquantity"); 

       HashMap<String, String> item = new HashMap<>(); 

       item.put("availableQuantity", availableQuantity); 
       item.put("defaultBranch", defaultBranch); 
       item.put("defaultInventoryBranch", defaultInventoryBranch); 
       item.put("inventoryBranch", inventoryBranch); 
       item.put("footage", footage); 
       item.put("anticipatedStockDate", anticipatedStockDate); 
       item.put("discontinuedItemFlag", discontinuedItemFlag); 
       item.put("mdc", mdc); 
       item.put("mdcquantity", mdcquantity); 

       itemList.add(item); 

       updateUI.runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         tvAvailableQuantity.setText(availableQuantity); 
         tvDefaultBranch.setText(defaultBranch); 
         tvDefaultInventoryBranch.setText(defaultInventoryBranch); 
         tvInventoryBranch.setText(inventoryBranch); 
         tvFootage.setText(footage); 
         tvAnticipatedStockDate.setText(anticipatedStockDate); 
         tvDiscontinuedItemFlag.setText(discontinuedItemFlag); 
         tvMdc.setText(mdc); 
         tvMdcquantity.setText(mdcquantity); 
        } 
       }); 

      } 
+1

예를 들어 'TextView tvAvailableQuantity = (TestView) findViewById (id)'와 같은 UI 변수를 초기화해야합니다. – anatoli

+0

질문을 편집하고 충돌의 스택 추적을 추가 할 수 있습니까? 아마도'runOnUiThread()'와 아무런 관련이 없습니다. 그러면 더 많은 정보를 얻을 수 있습니다. –

+0

다른 변수와 함께 onCreate 메서드를 사용하기 직전에이 작업을 수행했습니다. runOnUiThread와 관련된 코드 스 니펫 만 게시했습니다. 감사. –

답변

0

runOnUiThread() 구현이 올바르다. UI 스레드에서 실행되는 실행 파일을 전달합니다. 귀하의 경우에는

그러나, 나는 이것이 당신이 문자열로 AsyncTask를의 결과 유형을 변경하는 경우, 당신은 단순히 doInBackground() 방법에서 JSON_DATA을 반환하고 실행 onPostExecute()에 코드의 나머지 부분을 움직일 수조차 필요하지 않습니다 생각 어쨌든 UI 스레드.

+0

감사합니다. onCreate 전에 TextViews를 초기화했습니다. 그러나 runOnUiThread 또는 메서드를 사용하는 것이 더 나은 방법입니까? –

+0

일반적으로 runOnUiThread는 예를 들어 필요하면 사용할 수 있습니다. 다른 스레드에서 작업하는 동안 사용자에게 무엇인가를 보여줍니다. 귀하의 경우, 네트워크 액세스 (첫 번째 장소에서 별도의 스레드를 요구함)는 이미 끝났으므로 여기서는 제 제안이 더 바람직 할 것이라고 말하고 싶습니다. 더 읽기 쉽고 조금 더 짧습니다. Runnable 객체를 생성 할 필요는 없습니다. – Ridcully