1

我是 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

4 回答 4

2

-UI work on UI thread保留and始终是一个好习惯Non-UI work on Non-UI thread,但从 Android 版本Honey Comb开始,它成为了一项法律。

-您可以在background Non-UI thread.

-使用ThreadwithHandler来解决这个任务,或者使用 android 中称为PainLess Threading 的AsyncTask东西。

- Handler用于将后台非 UI 线程Thread的输出放到UI 线程,类似地,当您使用该方法在后台完成工作并通过方法将其输出发布到 UI 线程时 。AsyncTaskdoInBackground()onPostExecute()

例如:

new AsyncTask<Params, Progress, Result>() {

            @Override
            protected Result doInBackground(Params... params) {

                                // --- Do your network task here

                return null;
            }

            protected void onPostExecute(Result result) {

                                // --- Show the output on UI thread from here

                       };
        };
于 2013-06-07T08:35:04.890 回答
1

现在不可能在主 UIthread 中运行网络操作。如果您想能够执行 HTTP 请求,则必须使用另一个线程。正如 raghunandan 所说,您应该为此使用 asynctask

于 2013-06-07T08:26:13.980 回答
0

从您的代码看来,您已经在 onClick 方法中设置了一个新图像。

如果您想从服务器获取新 URL,然后显示图像,则需要使用 asynctask。如果它可以满足您的需求,您可以使用您已经拥有的同一个。只需从 onclick 启动它,例如

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

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

从您的 doInBackground 方法中,您应该返回一个作为 URL 的字符串。这被传递给 onPostExecute 方法。然后只需执行 image.setImageUrl(url);。

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

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

在您的 oncreate 中执行此操作一次,并使图像成为一个字段。然后,您可以从课堂上的任何地方访问图像。findViewById 是一个昂贵的调用,所以你只想做一次。

于 2013-06-07T08:37:34.090 回答
0

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

这是示例项目>>

于 2013-06-07T08:32:52.050 回答