mayumi Tai
mayumi Tai

Reputation: 55

Inheritance issues about Threads OnClickListener (android)

I have an textview who can enter a key word , and I press the button,it will show a parse Information over the current one.But this works fine however it's the close button that doesn't work.In first code,it have some problem about ThreadException .

private OnClickListener btsearchitemListener = new OnClickListener() 
        {
            public void onClick(View v) 
            {
                // TODO Auto-generated method stub
                    new Thread(new Runnable() {         
                    public void run() {
                        // TODO Auto-generated method stub                                          
                        editText1.setHint("");
                        URL url ;
                        String Http_keyWord = "https://tw.search.bid.yahoo.com/search/auction/product?p=%sqt=product&cid=0&clv=0", Http, Keyword;   
                        AllDatainfos = new ArrayList<HashMap<String, Object>>();
                        Keyword = editText1.getText().toString().trim();

                        tvspottempp = (TextView)findViewById(R.id.tvspottempp);
                        tvspottempp.setText("Keyword"+Keyword);

                        try
                        {
                            Http = String.format(Http_keyWord, UTF8EnCode(Keyword));
                            //Http = String.format(Http_keyWord, Keyword);
                            tvspottempp1 = (TextView)findViewById(R.id.tvspottempp1);
                            tvspottempp1.setText("Http"+Http);                          
                            url = new URL(Http);
                            tvspottempp2 = (TextView)findViewById(R.id.tvspottempp2);
                            tvspottempp2.setText("url"+url);
                            Document doc ;
                            /*tvspottempp2 = (TextView)findViewById(R.id.tvspottempp2);
                            tvspottempp2.setText("doc"+doc);*/
                            doc = Jsoup.parse(url, 30000000);   
                            tvspottempp2 = (TextView)findViewById(R.id.tvspottempp2);
                            tvspottempp2.setText("doc2"+doc);
                            Elements paramDocuments = doc.select("#srp_result_list, #srp_gaze_list").select(".grid-type.yui3-g > *");
                            Iterator localIterator = paramDocuments.select("#srp_result_list, #srp_gaze_list").select(".grid-type.yui3-g > *").iterator();
                          while (true)
                          {
                            if (!localIterator.hasNext())
                              return;
                            Element localElement1 = (Element)localIterator.next();
                            try
                            {
                              SearchResultItem localSearchResultItem = new SearchResultItem();
                              Element localElement2 = localElement1.select(".wrap").first();
                              parsePhoto(localSearchResultItem, localElement2);
                              parsePrice(localSearchResultItem, localElement2);
                              parseTitle(localSearchResultItem, localElement2);                    
                            }
                            catch (Exception localException2)
                            {
                              localException2.printStackTrace();
                            }
                          }
                        }
                        catch (Exception localException1)
                        {
                          localException1.printStackTrace();
                        }
                    }
                };              
                }
            };  

04-21 20:12:12.681: E/AndroidRuntime(20568):    FATAL EXCEPTION: Thread-10734
04-21 20:12:12.681: E/AndroidRuntime(20568):    android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
04-21 20:12:12.681: E/AndroidRuntime(20568):    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6804)
04-21 20:12:12.681: E/AndroidRuntime(20568):    at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1077)
04-21 20:12:12.681: E/AndroidRuntime(20568):    at android.view.View.requestLayout(View.java:16775)
04-21 20:12:12.681: E/AndroidRuntime(20568):    at android.view.View.requestLayout(View.java:16775)
04-21 20:12:12.681: E/AndroidRuntime(20568):    at android.view.View.requestLayout(View.java:16775)
04-21 20:12:12.681: E/AndroidRuntime(20568):    at android.view.View.requestLayout(View.java:16775)
04-21 20:12:12.681: E/AndroidRuntime(20568):    at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:358)
04-21 20:12:12.681: E/AndroidRuntime(20568):    at android.view.View.requestLayout(View.java:16775)
04-21 20:12:12.681: E/AndroidRuntime(20568):    at android.widget.TextView.checkForRelayout(TextView.java:7646)
04-21 20:12:12.681: E/AndroidRuntime(20568):    at android.widget.TextView.setHint(TextView.java:4588)
04-21 20:12:12.681: E/AndroidRuntime(20568):    at com.example.rsbuyclient.User_menu$1$1.run(User_menu.java:132)
04-21 20:12:12.681: E/AndroidRuntime(20568):    at java.lang.Thread.run(Thread.java:841)

So I chang thread methods.I create two thread in new code. But thread1 can't inheritance thread2 declare variables.For example : Url Http ... etc. How can I resolve it . Thanks.

private OnClickListener btsearchitemListener = new OnClickListener() 
    {
        public void onClick(View v) 
        {
            // TODO Auto-generated method stub
            //thread1 to get url
            Thread thread1 = new Thread(new Runnable() {
                public void run() {
                    // TODO Auto-generated method stub                                          
                    editText1.setHint("");

                    URL url ;
                    String Http_keyWord = "http://tw.search.bid.yahoo.com/search/auction/product?p=%s", Http, Keyword;
                    //String Http_keyWord = "https://tw.search.yahoo.com/search?p=u+zj6&fr=yfp&ei=utf-8&v=0", Http, Keyword;    


                    AllDatainfos = new ArrayList<HashMap<String, Object>>();

                    Keyword = editText1.getText().toString().trim();
                    tvspottempp = (TextView)findViewById(R.id.tvspottempp);
                    tvspottempp.setText("Keyword"+Keyword);                                             

                    Http = String.format(Http_keyWord, UTF8EnCode(Keyword));
                    tvspottempp1 = (TextView)findViewById(R.id.tvspottempp1);
                    tvspottempp1.setText("Http"+Http);
                     }
                   });

                    //thread2 to parse html
                    Thread thread2 = new Thread(new Runnable(){
                         public void run() {
                        //TagNode tagNode;
                        try
                        {
                            url = new URL(Http.toString());
                            tvspottempp2 = (TextView)findViewById(R.id.tvspottempp2);
                            tvspottempp2.setText("url "+url );

                            //tagNode = new HtmlCleaner().clean(url);
                            Document doc;                   
                            doc = Jsoup.parse(url, 30000000);
                            tvspottempp2 = (TextView)findViewById(R.id.tvspottempp2);
                            tvspottempp2.setText("doc"+doc);

                            Elements paramDocuments = doc.select("#srp_result_list, #srp_gaze_list").select(".grid-type.yui3-g > *");
                            Iterator localIterator = paramDocuments.select("#srp_result_list, #srp_gaze_list").select(".grid-type.yui3-g > *").iterator();

                          while (true)
                          {
                            if (!localIterator.hasNext())
                              return;
                            Element localElement1 = (Element)localIterator.next();
                            try
                            {
                              SearchResultItem localSearchResultItem = new SearchResultItem();
                              Element localElement2 = localElement1.select(".wrap").first();
                              parsePhoto(localSearchResultItem, localElement2);
                              parsePrice(localSearchResultItem, localElement2);
                              parseTitle(localSearchResultItem, localElement2);                    
                            }
                            catch (Exception localException2)
                            {
                              localException2.printStackTrace();
                            }
                          }
                        }catch (MalformedURLException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        catch (Exception localException1)
                        {
                          localException1.printStackTrace();
                        }
                    }});
                    thread1.start();
                    thread2.start();
                 }  
              };    

And I try to use runOnUiThread , but have problem about Parameter transformation.

It's change final URL url ; final String Http_keyWord = "tw.search.bid.yahoo.com/search/auction/product?p=%s";, Http, Keyword;

If Parameter transformation
url = new URL(Http.toString()); will be error

    private OnClickListener btsearchitemListener = new OnClickListener() 
        {
    public void onClick(View v) 
    {
        // TODO Auto-generated method stub          
        new Thread(new Runnable() {
            public void run() {
                // TODO Auto-generated method stub                                          
                editText1.setHint("");

                final URL url ;
                final String Http_keyWord = "http://tw.search.bid.yahoo.com/search/auction/product?p=%s", Http, Keyword;
                //String Http_keyWord = "https://tw.search.yahoo.com/search?p=u+zj6&fr=yfp&ei=utf-8&v=0", Http, Keyword;    


                AllDatainfos = new ArrayList<HashMap<String, Object>>();

                Keyword = editText1.getText().toString().trim();
                tvspottempp = (TextView)findViewById(R.id.tvspottempp);
                tvspottempp.setText("Keyword"+Keyword);                                             

                Http = String.format(Http_keyWord, UTF8EnCode(Keyword));
                tvspottempp1 = (TextView)findViewById(R.id.tvspottempp1);
                tvspottempp1.setText("Http"+Http);

                User_menu.this.runOnUiThread(new Runnable(){
                     public void run() {
                    //TagNode tagNode;
                    try
                    {
                        url = new URL(Http.toString());
                        tvspottempp2 = (TextView)findViewById(R.id.tvspottempp2);
                        tvspottempp2.setText("url"+url);

                        //tagNode = new HtmlCleaner().clean(url);
                        Document doc;                   
                        doc = Jsoup.parse(url, 30000000);
                        tvspottempp2 = (TextView)findViewById(R.id.tvspottempp2);
                        tvspottempp2.setText("doc"+doc);

                        Elements paramDocuments = doc.select("#srp_result_list, #srp_gaze_list").select(".grid-type.yui3-g > *");
                        Iterator localIterator = paramDocuments.select("#srp_result_list, #srp_gaze_list").select(".grid-type.yui3-g > *").iterator();

                      while (true)
                      {
                        if (!localIterator.hasNext())
                          return;
                        Element localElement1 = (Element)localIterator.next();
                        try
                        {
                          SearchResultItem localSearchResultItem = new SearchResultItem();
                          Element localElement2 = localElement1.select(".wrap").first();
                          parsePhoto(localSearchResultItem, localElement2);
                          parsePrice(localSearchResultItem, localElement2);
                          parseTitle(localSearchResultItem, localElement2);                    
                        }
                        catch (Exception localException2)
                        {
                          localException2.printStackTrace();
                        }
                      }
                    }catch (MalformedURLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    catch (Exception localException1)
                    {
                      localException1.printStackTrace();
                    }
                }});
                 }
               }).start();
             }  
          };

Upvotes: 0

Views: 76

Answers (1)

rupps
rupps

Reputation: 9897

You can't manipulate views inside a Thread, like you are doing. You are free to do whatever you want using Threads, but to manipulate any View you have to do it, exclusively, from the UI thread or you will get that fatal exception. You have several ways to do it:

activity.runOnUiThread(new Runnable() {
    @Override
    public void run() {
         ... manipulate your view
    }
});

runOnUiThread is a method that belongs to the Activity.

or at a view level:

view.post(new Runnable() {
    @Override
    public void run() {
         ... manipulate your view
    }
});

All views have a Handler that you can use to post Runnables that will be executed in the UI Thread.

or even

view.postDelayed(new Runnable() {
    @Override
    public void run() {
         ... manipulate your view
    }
}, DELAY_TIME);

you can schedule a Runnable to run with a time delay in the UI Thread

Besides, check out the class AsyncTask. It's the recommended method for doing the kind of background stuff you are doing, and allows to run code on a background thread and provides a place to write code that runs on the UI thread (onPostExecute) and even a means to report progress. Your code will be much cleaner instead of that big mess you have now :)

Upvotes: 1

Related Questions