我在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;
}
}
}
答案 0 :(得分:2)
- 保持UI work on UI thread
和Non-UI work on Non-UI thread
始终是一种很好的做法,但是从Android版Honey Comb
开始,它就成了法律。
- 您可以对background Non-UI thread
进行网络处理工作。
- 使用Thread
和Handler
来解决此任务,或者使用名为{strong 1的 PainLess Threading in android }}
- AsyncTask
与Handler
一起使用,以便将输出从后台非UI线程放到UI线程,类似当您使用Thread
方法时,使用AsyncTask
方法在UI线程中通过doInBackground()
执行在后台工作并发布其输出方法
<强>例如强>
onPostExecute()
答案 1 :(得分:1)
现在无法在主UIthread中运行网络操作。如果你想要能够做一个HTTP请求,你必须使用另一个线程。 正如raghunandan所说,你应该使用asynctask来实现这个
答案 2 :(得分:0)
您也可以将WebImageView组件用于此目的
这里是示例代码(改编自不同的地方)
WebImageView >>
WebService >>
答案 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是一个昂贵的调用,所以你只想做一次。