UIThread中的HTTP POST请求

时间:2013-06-07 08:21:12

标签: java android

我在Android开发方面很新,这是我的第一个应用程序。

问题可能非常简单,但我找不到解决方案。

此应用程序是一个简单的ImageViewer,其中应用程序必须连接到服务器,并且根据某些数据,服务器将返回特定图像。 该图像显示在屏幕上,点击它将获得另一个。 就是这样!

我可以看到我无法从UIThread运行http post查询,必须在后台运行。 然而,目的是当用户点击图像时。

我有一个AsyncTask,其中创建应用程序将被服务器识别,他们将交换一些数据。 我m using a library SmartImageViewer (making possible load images from a url). At the moment in my code I通过计数器++加载图像,到目前为止它的工作。 但是每次用户点击它并在屏幕上显示时,我都需要获取图像URL。

public class MainActivity extends Activity implements OnClickListener {
SmartImageView imageSwitcher;
String SERVER_IP;
String APP_ID;
String DEVICE_ID;
Integer counter = 0;

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

    DB_Queries db = new DB_Queries(getApplicationContext());
    Cursor c = db.getServerIPAndAppId();
    StringBuilder app_id = new StringBuilder();
    StringBuilder server_ip = new StringBuilder();
    if (c.moveToFirst()) {
        do {
            server_ip.append(c.getString(c.getColumnIndex("server_ip")));
            app_id.append(c.getString(c.getColumnIndex("app_id")));
        } while (c.moveToNext());
    }
    db.close();

    SERVER_IP = server_ip.toString();
    APP_ID = app_id.toString();

    ServerConnect connect = new ServerConnect();
    connect.execute("http://" + server_ip + "/");

    SmartImageView image = (SmartImageView) this
            .findViewById(R.id.image_switcher);
    image.setImageUrl("http://localhost/public/albums/1/_(99).jpg");

    imageSwitcher = (SmartImageView) findViewById(R.id.image_switcher);
    imageSwitcher.setOnClickListener(this);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public void onClick(View v) {
    if (v.getId() == imageSwitcher.getId()) {
        counter++;
        Toast.makeText(getApplicationContext(), "Image is clicked",
                Toast.LENGTH_LONG).show();
        SmartImageView image = (SmartImageView) this
                .findViewById(R.id.image_switcher);
        image.setImageUrl("http://localhost/public/albums/1/_("
                + counter + ").jpg");
    }
}

private class ServerConnect extends AsyncTask<String, Void, Void> {

    @Override
    protected Void doInBackground(String... params) {
        String DEVICE_ID = Secure.getString(getContentResolver(),
                Secure.ANDROID_ID);
        DB_Queries db = new DB_Queries(getApplicationContext());
        Cursor c = db.getSettings();
        String APP_ID = null;
        String INSTALLED_AT = null;
        String TOKEN = null;
        if (c.moveToFirst()) {
            do {
                APP_ID = c.getString(c.getColumnIndex("app_id"));
                INSTALLED_AT = c
                        .getString(c.getColumnIndex("installed_at"));
                TOKEN = c.getString(c.getColumnIndex("token"));
            } while (c.moveToNext());
        }

        HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost(params[0]);
        post.addHeader("Content-type", "application/x-www-form-urlencoded");
        List<NameValuePair> pair = new ArrayList<NameValuePair>();
        pair.add(new BasicNameValuePair("device_id", DEVICE_ID));
        pair.add(new BasicNameValuePair("app_id", APP_ID.toString()));
        pair.add(new BasicNameValuePair("token", TOKEN.toString()));

        try {
            post.setEntity(new UrlEncodedFormEntity(pair));
            HttpResponse response = client.execute(post);
            InputStream is = response.getEntity().getContent();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            StringBuilder str = new StringBuilder();
            String chunk = null;

            while ((chunk = br.readLine()) != null) {
                str.append(chunk);
            }

            final String query_response = str.toString().trim();

            if (query_response.equals("HH@K2i")) {
                Cursor delete = db.updateAuth();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        db.close();

        return null;
    }

}

}

4 个答案:

答案 0 :(得分:2)

- 保持UI work on UI threadNon-UI work on Non-UI thread始终是一种很好的做法,但是从Android版Honey Comb开始,它就成了法律。

- 您可以对background Non-UI thread进行网络处理工作。

- 使用ThreadHandler来解决此任务,或者使用名为{strong 1的 PainLess Threading in android }}

- AsyncTaskHandler一起使用,以便将输出从后台非UI线程放到UI线程,类似当您使用Thread方法时,使用AsyncTask方法在UI线程中通过doInBackground()执行在后台工作发布其输出方法

<强>例如

onPostExecute()

答案 1 :(得分:1)

现在无法在主UIthread中运行网络操作。如果你想要能够做一个HTTP请求,你必须使用另一个线程。 正如raghunandan所说,你应该使用asynctask来实现这个

答案 2 :(得分:0)

您也可以将WebImageView组件用于此目的 这里是示例代码(改编自不同的地方)
WebImageView >>
WebService >>

这里是example project >>

答案 3 :(得分:0)

您的代码似乎已经在onClick方法中设置了一个新图像。

如果您想从服务器获取新URL,然后显示图像,则需要使用asynctask。如果它符合你的要求,你可以使用你已经拥有的那个。 只需从onclick开始,例如

onClick(View v){
new MyAsynctask().execute();
}

Asynctasks有一个onPostExecute方法,该方法在doInbackground方法运行后运行。 onPostExecute在UI线程上运行。您可以在此处设置新图像。

从doInBackground方法中,您应该返回一个String,即URL。这将传递给onPostExecute方法。然后只需做一个image.setImageUrl(url);。

还有一件事,在你的onClick中你每次都绑定视图:

  SmartImageView image = (SmartImageView) this
                .findViewById(R.id.image_switcher);

在你的oncreate中执行一次,并使图像成为一个字段。然后,您可以从班级中的任何位置访问图像。 findViewById是一个昂贵的调用,所以你只想做一次。