2017-01-05 9 views
0

RESTfulなサービスからxmlを取り出し、XMLPullParserを配置しています。私はその情報をリストビューに取り込もうとしています。私はXML構文解析が初めてで、なぜレスポンスのデータをリストに入れるのかわからない。以下のようにXMLを解析するときに、ビュー階層を作成した元のスレッドのみがそのビューに触れることができます

私のコードは次のとおりです。

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 
     context = getApplicationContext(); 

     listView = (ListView) findViewById(R.id.contactListView); 

     OkHttpClient client = getUnsafeOkHttpClient(); 
     Request request = new Request.Builder() 
       .url(myURL) 
       .build(); 
     client.newCall(request).enqueue(new Callback() { 
      @Override 
      public void onFailure(Call call, IOException e) { 
       e.printStackTrace(); 
      } 

      @Override 
      public void onResponse(Call call, Response response) throws IOException { 
       final String responseData = response.body().string(); 
       InputStream stream = new ByteArrayInputStream(responseData.getBytes()); 
       List<PeepWithPic> peepWithPics; 
       XMLPullParserHandler parserHandler = new XMLPullParserHandler(); 
       peepWithPics = parserHandler.parse(stream); 
       ArrayAdapter<PeepWithPic> adapter = new ArrayAdapter<>(getApplicationContext(), 
         R.layout.contact_cardview_layout, peepWithPics); 
       listView.setAdapter(adapter); 


      } 
     }); 

     FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 
     fab.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) 
         .setAction("Action", null).show(); 
      } 
     }); 
    } 

public class XMLPullParserHandler { 
    List<PeepWithPic> peepWithPicList; 
    private PeepWithPic peepWithPic; 
    private String text; 

    public XMLPullParserHandler() { 
     peepWithPicList = new ArrayList<>(); 
    } 

    public List<PeepWithPic> getPeepWithPicList() { 
     return peepWithPicList; 
    } 

    public List<PeepWithPic> parse(InputStream is) { 
     XmlPullParserFactory factory = null; 
     XmlPullParser parser = null; 
     try { 
      factory = XmlPullParserFactory.newInstance(); 
      factory.setNamespaceAware(true); 
      parser = factory.newPullParser(); 

      parser.setInput(is, null); 

      int eventType = parser.getEventType(); 
      while (eventType != XmlPullParser.END_DOCUMENT) { 
       String tagname = parser.getName(); 
       switch (eventType) { 
        case XmlPullParser.START_TAG: 
         if (tagname.equalsIgnoreCase("PeepWithPic")) { 
          // create a new instance of employee 
          peepWithPic = new PeepWithPic(); 
         } 
         break; 

        case XmlPullParser.TEXT: 
         text = parser.getText(); 
         break; 

        case XmlPullParser.END_TAG: 
         if (tagname.equalsIgnoreCase("PeepWithPic")) { 
          // add employee object to list 
          peepWithPicList.add(peepWithPic); 
         } else if (tagname.equalsIgnoreCase("First_name")) { 
          peepWithPic.setFirst_name(text); 
         } else if (tagname.equalsIgnoreCase("Last_name")) { 
          peepWithPic.setLast_name(text); 
         } else if (tagname.equalsIgnoreCase("Payroll_title")) { 
          peepWithPic.setPayroll_title(text); 
         /*} else if (tagname.equalsIgnoreCase("email")) { 
          peepWithPic.setEmail(text);*/ 
         } /*else if (tagname.equalsIgnoreCase("type")) { 
          peepWithPic.set(text); 
         }*/ 
         break; 

        default: 
         break; 
       } 
       eventType = parser.next(); 
      } 

     } catch (XmlPullParserException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return peepWithPicList; 
    } 
} 
+0

[CalledFromWrongThreadExceptionの可能な複製:ビュー階層を作成した元のスレッドのみがビューにアクセスできます](http://stackoverflow.com/questions/3280141/calledfromwrongthreadexception-only-the-original-thread-that-c​​reated-a -view-hie) – Isaac

答えて

1

あなたはUIスレッドの外のビューを変更しようとすると、エラーが発生しました。問題の原因となっているスタックトレースを持たずに、問題を解決するための正確な答えを与えることはできません。しかしここで問題が始まる場所があります:onResponseコールの中からUIを操作しています。あなたはこのように見えるようにコードをアップデートしてみてくださいすることができます

client.newCall(request).enqueue(new Callback() { 
      Handler mainHandler = new Handler(context.getMainLooper()); 
      @Override 
      public void onFailure(Call call, IOException e) { 
       e.printStackTrace(); 
      } 

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

       mainHandler.post(new Runnable() { 

        @Override 
        public void run() { 
         List<PeepWithPic> peepWithPics; 
         XMLPullParserHandler parserHandler = new XMLPullParserHandler(); 
         peepWithPics = parserHandler.parse(stream); 
         ArrayAdapter<PeepWithPic> adapter = new ArrayAdapter<>(getApplicationContext(), 
           R.layout.contact_cardview_layout, peepWithPics); 
         listView.setAdapter(adapter); 
        } 
       }); 


      } 
     }); 

をしかし、あなたはまた、それは、これを解析するために時間がかかりすぎる場合は、ANRを得ることができ、この内XmlPullParserを有しているからです。したがって、listViewの呼び出しをonResponseの外に移動し、XmlPullParserからHandler mainHandler = new Handler(context.getMainLooper());と同様のことを行うと、UIの更新をメインスレッドに戻すことができます。

+0

Handlerを追加することで、私が3つの方法を追加して、そうすることができるかどうかはわかりません。しかし、私はCalledFromWrongThreadExctiopnを取得している行はlistView.setAdapter(アダプタ)にあります –

+0

速い答えは、ハンドラが別のスレッドに物を渡すことができるということです。この場合、タッチするべき唯一のメインスレッドですUIコンポーネント。 – CodyEngel

+0

公開メソッドの中でリストビューを渡しますか?申し訳ありませんまだAndroidには初めてのことで、ハンドラを使用したことはありません。 –

関連する問題