0

我正在开发一个适用于 Android 的大型程序,并且正在尝试使该程序的货币转换器部分正常工作。全面披露:我从http://firstamong.com/building-android-currency-converter/找到了它,它是关于如何构建实时货币转换器的教程。我将发布有问题的代码,然后是 logcat。发生的错误是当我尝试从一种货币转换为另一种货币时,应用程序说它被迫停止。但是,“无效”部分有效(两个货币字段相同的情况。)任何帮助将不胜感激:

代码:

public class currency_converter extends Activity {

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

    }
}

}

日志猫:

10-30 00:59:48.164  20591-20591/com.example.travelapplication E/AndroidRuntime﹕ FATAL EXCEPTION: main
android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1128)
        at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
        at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
        at java.net.InetAddress.getAllByName(InetAddress.java:214)
        at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
        at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
        at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
        at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:365)
        at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:587)
        at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:511)
        at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:489)
        at com.example.travelapplication.currency_converter.getJson(currency_converter.java:93)
        at com.example.travelapplication.currency_converter$1.onClick(currency_converter.java:68)
        at android.view.View.performClick(View.java:4222)
        at android.view.View$PerformClick.run(View.java:17620)
        at android.os.Handler.handleCallback(Handler.java:800)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:194)
        at android.app.ActivityThread.main(ActivityThread.java:5391)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:525)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
        at dalvik.system.NativeStart.main(Native Method)
4

4 回答 4

1

你得到:

NetworkOnMainThreadException

问题是您在 Activity 中调用函数 getJson()。

使用异步任务:

public class ProcessTask extends AsyncTask<Void, Integer, String>{

    public ProcessTask() {
        // TODO Auto-generated constructor stub

    }

    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(Void... params) {
        // TODO Auto-generated method stub

        //your code of parsing
        StringBuilder build = new StringBuilder();
        HttpClient client = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);  //your yahooapi url goes here
        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();
    }

    @Override
    protected void onPostExecute(String result) {
        // TODO Auto-generated method stub

        super.onPostExecute(result);
    }
}
于 2014-10-30T05:14:00.933 回答
1

尝试这个,,

您在其主线程上执行网络操作。这就是为什么你得到NetworkOnMainThreadException

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
            {
                GetResponseData abcd = GetResponseData(t);
                abcd.execute();
            }
        }
    });
于 2014-10-30T05:09:05.557 回答
1

看起来你在你的 android manifest 中有严格模式。当您在主线程上进行网络调用时,严格模式会报错。您可以禁用严格模式,或者更好的方法是将您的网络调用放入异步任务中。有问题的网络调用是

HttpResponse response = client.execute(httpGet);

里面public String getJson(String url)

您需要的异步任务已经存在,您只需要使用它

更改此 else 语句

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

对此

else {
    new GetResponseData().execute("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=");
}
于 2014-10-30T05:10:04.643 回答
0

这将有助于使用它:

public class CurrencyConverter extends Fragment {
    public CurrencyConverter() {
    }
    TextView t;
    public int to;
    public int from;
    public String[] val;
    public String s;
    String exResult;
    public Handler handler;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {


         View rootView = inflater.inflate(R.layout.currency_converter, container, false);
        t= (TextView) rootView.findViewById(R.id.textView4);
        Spinner s1 = (Spinner) rootView.findViewById(R.id.spinner1);
        Spinner s2 = (Spinner) rootView.findViewById(R.id.spinner2);
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
                this.getActivity(), 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) rootView.findViewById(R.id.button1);
        b.setOnClickListener(new View.OnClickListener() {
            public void onClick(View View) {



                if (from == to) {
                    Toast.makeText(getActivity().getApplicationContext(), "Invalid", 4000).show();
                } else {
                    new calculate().execute();

                }
            }

        });
        return rootView;
    }

    public class calculate extends AsyncTask<String, String, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();

        }

        @Override
        protected String doInBackground(String... args) {

            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);
                 exResult = jObj.getJSONObject("query").getJSONObject("results").getJSONObject("rate").getString("Rate");


            } 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();
            }
            return exResult;

        }
        @Override
        protected void onPostExecute(String exResult) {

           t.setText(exResult);
        }



       }

    public String getJson(String url)throws  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();
    }

        public class spinOne implements AdapterView.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
            }

    }
}
于 2016-05-11T08:56:40.450 回答