【问题标题】:Android app crashes on network requestAndroid 应用程序因网络请求而崩溃
【发布时间】:2013-11-29 12:19:54
【问题描述】:

我在我的应用程序中集成了一个货币转换器,但是当我尝试从互联网获取结果时,应用程序崩溃了。我收到一个关于:android.os.NetworkOnMainThreadException 的错误,有人说你必须添加 asynctask 才能解决问题,因为它在主线程上运行。那么如何在我当前的代码中做到这一点呢?

下面是代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;


import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

public class Activity_Currency_Converter extends DashBoardActivity {
    public int to;
    public int from;
    public String [] val;
    public String s;
    public Handler handler;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_currency_converter);
        Spinner s1 = (Spinner) findViewById(R.id.spinner1);
        Spinner s2 = (Spinner) findViewById(R.id.spinner2);
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
                this, R.array.name, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.select_dialog_singlechoice);
        val  = getResources().getStringArray(R.array.value);
        s1.setAdapter(adapter);
        s2.setAdapter(adapter);
        s1.setOnItemSelectedListener(new spinOne(1));
        s2.setOnItemSelectedListener(new spinOne(2));
        Button b = (Button) findViewById(R.id.button1);
        b.setOnClickListener(new OnClickListener(){
            public void onClick(View v) {
                TextView t = (TextView) findViewById(R.id.textView4);   
                if(from == to)
                {
                    Toast.makeText(getApplicationContext(), "Invalid", 4000).show();
                }
                else
                {                                       
                      try {
                         s = getJson("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22"+val[from]+val[to]+"%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=");                       
                        JSONObject jObj;
                        jObj = new JSONObject(s);
                        String exResult = jObj.getJSONObject("query").getJSONObject("results").getJSONObject("rate").getString("Rate");
                        t.setText(exResult);
                        } catch (JSONException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        catch (ClientProtocolException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }                                                    
                    }                                           
                }                               
        });
    }
    public String getJson(String url)throws ClientProtocolException, IOException {

        StringBuilder build = new StringBuilder();
        HttpClient client = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);
        HttpResponse response = client.execute(httpGet);
        HttpEntity entity = response.getEntity();
        InputStream content = entity.getContent();
        BufferedReader reader = new BufferedReader(new InputStreamReader(content));
        String con;
        while ((con = reader.readLine()) != null) {
                    build.append(con);
                }
        return build.toString();
    }
    private class spinOne implements OnItemSelectedListener
    {
        int ide;
        spinOne(int i)
        {
            ide =i;
        }
        public void onItemSelected(AdapterView<?> parent, View view,
                int index, long id) {
            if(ide == 1)
                from = index;
            else if(ide == 2)
                to = index;

        }

        public void onNothingSelected(AdapterView<?> arg0) {
            // TODO Auto-generated method stub  
        }

    }
}

Logcat 日志:

11-27 13:58:17.120: E/AndroidRuntime(1470): android.os.NetworkOnMainThreadException
11-27 13:58:17.120: E/AndroidRuntime(1470):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1133)
11-27 13:58:17.120: E/AndroidRuntime(1470):     at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
11-27 13:58:17.120: E/AndroidRuntime(1470):     at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
11-27 13:58:17.120: E/AndroidRuntime(1470):     at java.net.InetAddress.getAllByName(InetAddress.java:214)
11-27 13:58:17.120: E/AndroidRuntime(1470):     at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
11-27 13:58:17.120: E/AndroidRuntime(1470):     at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
11-27 13:58:17.120: E/AndroidRuntime(1470):     at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
11-27 13:58:17.120: E/AndroidRuntime(1470):     at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
11-27 13:58:17.120: E/AndroidRuntime(1470):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
11-27 13:58:17.120: E/AndroidRuntime(1470):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
11-27 13:58:17.120: E/AndroidRuntime(1470):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)

【问题讨论】:

    标签: android android-asynctask android-internet androidhttpclient


    【解决方案1】:

    试试这个,

    public class Activity_Currency_Converter extends DashBoardActivity {
        public int to;
        public int from;
        public String [] val;
        public String s;
        public Handler handler;
    
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_currency_converter);
            Spinner s1 = (Spinner) findViewById(R.id.spinner1);
            Spinner s2 = (Spinner) findViewById(R.id.spinner2);
            ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
                    this, R.array.name, android.R.layout.simple_spinner_item);
            adapter.setDropDownViewResource(android.R.layout.select_dialog_singlechoice);
            val  = getResources().getStringArray(R.array.value);
            s1.setAdapter(adapter);
            s2.setAdapter(adapter);
            s1.setOnItemSelectedListener(new spinOne(1));
            s2.setOnItemSelectedListener(new spinOne(2));
            Button b = (Button) findViewById(R.id.button1);
            b.setOnClickListener(new OnClickListener(){
                public void onClick(View v) {
                    TextView t = (TextView) findViewById(R.id.textView4);   
                    if(from == to)
                    {
                        Toast.makeText(getApplicationContext(), "Invalid", 4000).show();
                    }
                    else
                    {                                       
                          new GetResponseData(t).execute();                              
                        }                                           
                    }                               
            });
        }
        public String getJson(String url)throws ClientProtocolException, IOException {
    
            StringBuilder build = new StringBuilder();
            HttpClient client = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);
            HttpResponse response = client.execute(httpGet);
            HttpEntity entity = response.getEntity();
            InputStream content = entity.getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(content));
            String con;
            while ((con = reader.readLine()) != null) {
                        build.append(con);
                    }
            return build.toString();
        }
        private class spinOne implements OnItemSelectedListener
        {
            int ide;
            spinOne(int i)
            {
                ide =i;
            }
            public void onItemSelected(AdapterView<?> parent, View view,
                    int index, long id) {
                if(ide == 1)
                    from = index;
                else if(ide == 2)
                    to = index;
    
            }
    
            public void onNothingSelected(AdapterView<?> arg0) {
                // TODO Auto-generated method stub  
            }
    
        }
        class GetResponseData extends AsyncTask<String, String, String> {
             private ProgressDialog dialog;
             private ArrayList<String> titleList;
             private TextView textView;
    
             public GetResponseData(TextView textView) {
                 this.textView=textView;
            }
    
             @Override
             protected void onPreExecute() {
             super.onPreExecute();
             dialog = ProgressDialog.show(Activity_Currency_Converter.this, "", "Loading",
             false);
             }
    
             @Override
             protected String doInBackground(String... params) {
    
                 try {
                     String s = getJson("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22"+val[from]+val[to]+"%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=");                       
                    JSONObject jObj;
                    jObj = new JSONObject(s);
                    String exResult = jObj.getJSONObject("query").getJSONObject("results").getJSONObject("rate").getString("Rate");
                   return exResult;
                    } catch (JSONException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        return null;
                    }
                    catch (ClientProtocolException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        return null;
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        return null;
                    }                      
    
    
    
    
             }
    
             @Override
             protected void onPostExecute(String result) {
             super.onPostExecute(result);
             if (dialog != null)
                 dialog.dismiss();
             if(result!=null)
             {
              textView.setText(result);
             }
             }
    
             }
    }
    

    【讨论】:

      【解决方案2】:

      使用 Asynchtask 执行网络相关操作.. 查看更多详情 NetworkOnMainThreadAsynchtask

      【讨论】:

        【解决方案3】:

        创建StringBuilder 类级别,相应地创建您的ProgressDialog。 在您的 getJSON 方法中创建一个像这样的异步任务

        new AsyncTask<Void, Void, Void>() {
        
                protected void onPreExecute() {
                  //Your code
                }
        
                @Override
                protected Void doInBackground(Void... params) {
                StringBuilder build = new StringBuilder();
                HttpClient client = new DefaultHttpClient();
                HttpGet httpGet = new HttpGet(url);
                HttpResponse response = client.execute(httpGet);
                HttpEntity entity = response.getEntity();
                InputStream content = entity.getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(content));
                String con;
                while ((con = reader.readLine()) != null) {
                            build.append(con);
                        }
                return null;
                }
        
                protected void onPostExecute(Void result) {
                  //Update UI from here
                }
              }.execute();
        

        【讨论】:

          【解决方案4】:

          使用 AsyncTask 作为

          class myAsyncTask extends AsyncTask<String[] ,String,String>
          {
              String s=null;
              String output=null;
              JSONObject main;
          
              @Override
              protected void onPreExecute() 
              {   
          
          
              }
          
              @Override
              protected String doInBackground(String[]... val) {
          
                  s = getJson("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22"+val[from]+val[to]+"%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=");                       
                              JSONObject jObj;
                              jObj = new JSONObject(s);
                              String exResult = jObj.getJSONObject("query").getJSONObject("results").getJSONObject("rate").getString("Rate");
          
                  return exResult;
              }
              @Override
              protected void onPostExecute(String result) {
                  super.onPostExecute(result);
                  t.setText(result);
                       }
          }
          

          然后从 'else' 块中调用以下方法

          new myAsyncTask().execute(val);
          

          【讨论】:

            【解决方案5】:

            应用程序由于严格的模式政策而崩溃,请在您向服务发送请求或连接到网络之前插入以下给定行:

             ThreadPolicy tp = ThreadPolicy.LAX;
             StrictMode.setThreadPolicy(tp);
            

            希望对你有帮助:)

            【讨论】:

              猜你喜欢
              • 2017-10-16
              • 1970-01-01
              • 1970-01-01
              • 2014-10-30
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-03-25
              • 1970-01-01
              相关资源
              最近更新 更多