我有一个Android应用程序,它使用相同的服务器PHP脚本在数据库中做一些事情并做出响应,然后相应地更新你的屏幕。
大约 60% 的时间它很快。但有时手机的UI长时间挂起,这确实让用户感到困惑,因为他们认为出了问题。
此外,如果应用程序屏幕长时间挂起,我只是引用它,我看到数据都在那里,所以问题出在数据插入数据库之后。
这是我的安卓代码:
我有一个扩展 BaseListActivity 的 TopicActivity 扩展了 ListActivity
在主题活动中,我首先设置了如下列表:
DiscussionMessage d = new DiscussionMessage ();
d.setMessage( "Please wait while the discussion load..." );
discussion.add(d);
adapter = new ArrayAdapter<DiscussionMessage>(
this,R.layout.discussion_comments,
discussion);
setListAdapter(adapter);
然后当发生某些事情时,我调用 sendFeedback 方法,如下所示:
public void sendFeedback( String c , String user_id , String problem_id ,
String recent_topic_id )
{
String[] params = new String[]
{ "the_remote_url",
c , user_id, problem_id , recent_topic_id };
AddComment task = new AddComment();
task.execute(params);
}
然后是AddComment类的外观。 它位于 TopicActivity 类中:
public class AddComment extends AsyncTask<String, Void, String>
{
@Override
protected String doInBackground(String... theParams)
{
String myUrl = theParams[0];
final String comment = theParams[1];
final String user_id = theParams[2];
final String problem_id = theParams[3];
final String recent_topic_id = theParams[4];
String charset = "UTF-8";
String response = null;
try
{
String query = String.format("comment=%s&user_id=%s&problem_id=%s&recent_topic_id=%s",
URLEncoder.encode( comment, charset),
URLEncoder.encode( user_id, charset),
URLEncoder.encode( problem_id, charset),
URLEncoder.encode( recent_topic_id, charset)
);
final URL url = new URL( myUrl + "?" + query );
final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.connect();
InputStream stream = conn.getInputStream();
byte[] stream_buffer = new byte[8196];
int readCount;
StringBuilder stream_builder = new StringBuilder();
while ((readCount = stream.read(stream_buffer)) > -1)
{
stream_builder.append(new String(stream_buffer, 0, readCount));
}
}
catch (Exception e)
{
e.printStackTrace();
}
return response;
}
@Override
protected void onPostExecute(String result)
{
if ( result != null )
{
Toast.makeText(getApplicationContext(), "Could not get the current discussion.", Toast.LENGTH_LONG).show();
}
else
{
try
{
JSONArray obj = new JSONArray(result);
if ( obj != null )
{
discussion.clear();
if ( obj.length() == 0 )
{
DiscussionMessage message = new DiscussionMessage ( );
message.setMessage("No messages in this discussion.");
discussion.add( message );
}
else
{
for ( int i = 0; i < obj.length(); i++ )
{
JSONObject o = obj.getJSONObject(i);
String comment = o.getString("comment");
String commenter_id = o.getString("commenter_id");
String comment_id = o.getString("comment_id");
String first_name = o.getString("first_name");
String last_name = o.getString("last_name");
String is_private = o.getString("is_private");
DiscussionMessage d = new DiscussionMessage ( );
d.setMessage(comment);
d.setAuthorId(commenter_id);
d.setMessageId(comment_id);
d.setAuthorName(first_name);
discussion.add( d );
}
}
adapter.notifyDataSetChanged();
// Now clear the text area of text.
EditText comment = (EditText) findViewById(R.id.discussion_comment);
comment.setText( "" );
}
}
catch ( Exception e )
{
// Do something.
}
}
}
}
从中可以判断出我可能做错了什么吗?我如何使用异步或列表适配器可能有问题吗?
非常感谢修复和/或调试此问题的想法!
将 JSON 解析和创建 DiscussionMessage
对象移动到 doInBackground()
,因为它们需要时间并且应该在后台线程上运行。将DiscussionMessage
物体倒入Adapter
中,并在onPostExecute()
中调用notifyDataSetChanged()
。
除此之外,正如Fuzzical Logic指出的那样,你需要精确地确定你的困难在哪里,无论是使用Log
调用还是Traceview或其他什么。例如,您的 Web 服务有时响应速度很慢吗?