我正在尝试创建一个与Azure SQL数据库一起使用的聊天活动。逻辑是所有消息都列在listView上,如果数据库中的消息表上有新数据,实例服务将检查它,如果有,则清除ChatAdapter并添加所有数据,然后再将setAdapter设置为listView。
当我打开活动时,它可以工作,我可以发送消息,它直接进入数据库并进入屏幕,但活动工作缓慢,spikey,有时冻结半秒。也许如果我在intentservice中进行数据库检查,它可以解决问题,但我不想在没有建议的情况下做任何事情。
我不是业余爱好所以我的代码看起来像一团糟。我也“必须”用这个逻辑来解决这个问题。所以需要一些建议,比如“不要在这里做这个任务,在那里做。不要使用InstanceService,使用AsyncTask ......”而不是“使用聊天服务,移动服务,不要用数据库做.... “等等。
我的listView刷新代码:
public static boolean refreshList()
{
if(chatArrayAdapter!=null) {
chatArrayAdapter.Reset();
chatArrayAdapter.notifyDataSetChanged();
listView.deferNotifyDataSetChanged();
chatArrayAdapter.notifyDataSetChanged();
Mes = null;
}
try {
SqlCon.httpIslemleri(); /** AsyncTask to connect Db**/
Connection con = SqlCon.returnCon(); /** Returns DB Connection **/
Statement getMes = con.createStatement();
SetUser User = Intro.stUser;
Mes = null;
Mes = getMes.executeQuery("select * from tb_ms where (ms_sender = "+User.getid()+" or ms_sender = "+value+") and (ms_getter = "+User.getid()+" or ms_getter = "+value+")");
while(Mes.next())
{
if(Mes.getInt("ms_sender")==User.getid())
{
side=false;
}
else if(Mes.getInt("ms_getter")==User.getid())
{
side=true;
}
chatArrayAdapter.add(new ChatMessage(side, Mes.getString("ms_mes")));
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
return true;
}
CheckMesChanges功能。检查消息表是否更改:
public static boolean CheckMesChanges(ResultSet Mes)
{
SqlCon.httpIslemleri();
Connection con = SqlCon.returnCon();
Statement getMes = null;
try {
getMes = con.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
SetUser User = Intro.stUser;
try {
MesCheck = getMes.executeQuery("select * from tb_ms where (ms_sender = "+User.getid()+" or ms_sender = "+value+") and (ms_getter = "+User.getid()+" or ms_getter = "+value+")");
} catch (SQLException e) {
e.printStackTrace();
}
if(MesCheck==Mes)
{
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
else
{
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
return true;
}
和我的Intent Service控制CheckMesChanges并在它返回true时调用refreshList:
public class IntentMesControl extends IntentService {
public IntentMesControl(String name) {
super(name);
}
final Handler handler = new Handler();
protected void onHandleIntent() {
if(ChatBubbleActivity.CheckMesChanges(ChatBubbleActivity.Mes)==true)
{
ChatBubbleActivity.refreshList();
}
else {
}
handler.postDelayed(new Runnable() {
public void run() {
onHandleIntent();
}
}, 500);
}
@Override
protected void onHandleIntent(final Intent intent) {
if(ChatBubbleActivity.CheckMesChanges(ChatBubbleActivity.Mes)==true)
{
ChatBubbleActivity.refreshList();
}
else {
}
handler.postDelayed(new Runnable() {
public void run() {
onHandleIntent();
}
}, 500);
}
}
我在onCreate of activity上启动IntentMesControl。那么你能帮助我,给我一些建议让我的活动更加稳定和快速吗?谢谢。
答案 0 :(得分:0)
针对可能遇到同样问题的其他人的解决方案:
连接到数据库的每个Asynctask都需要一些时间来建立连接。任何使用活动功能的服务都需要一些时间。因此,当您多次调用此Asynctask时,它会冻结您的活动。
解决方案是,如果要创建SQL连接,请检查需要创建的数据和刷新列表视图:
一个IntentService,它将连接数据库,获取数据并检查数据,并在数据发生变化时返回数据。
一个不连接数据库但获取数据并刷新列表的函数。
通过这种方式,您的连接和数据检查将在后台工作,当数据更改时,asynctask将调用函数刷新列表。
它解决了我的问题。如果有人想使用新代码就好了。
刷新listView的功能:
public static boolean refreshList2(ResultSet Mes2)
{
if(chatArrayAdapter!=null) {
chatArrayAdapter.Reset();
chatArrayAdapter.notifyDataSetChanged();
/*listView.setAdapter(null);*/
listView.deferNotifyDataSetChanged();
chatArrayAdapter.notifyDataSetChanged();
}
SetUser User = Intro.stUser;
try{
while(Mes2.next())
{
if(Mes2.getInt("ms_sender")==User.getid())
{
side=true;
}
else if(Mes2.getInt("ms_getter")==User.getid())
{
side=false;
}
chatArrayAdapter.add(new ChatMessage(side, Mes2.getString("ms_mes")));
}
Mes3 = Mes2;
} catch (SQLException e) {
e.printStackTrace();
}
return true;
}
}
用于连接数据库和检查数据的Intent服务是否已更改:
public class IntentMesServicev2 extends IntentService {
public IntentMesServicev2(String name) {
super(name);
}
final Handler handler = new Handler();
Connection con;
ResultSet Mes;
SetUser User = Intro.stUser;
int value = ChatBubbleActivity.value;
public void onCreate (){
httpIslemleri();
}
protected void onHandleIntent() {
httpIslemleri();
try {
Statement state = con.createStatement();
Mes = state.executeQuery("select * from tb_mes where (ms_sender = " + User.getid() + " or ms_sender = " + value + ") and (ms_getter = " + User.getid() + " or ms_getter = " + value + ")");
} catch (SQLException e) {
e.printStackTrace();
}
if (Mes != ChatBubbleActivity.Mes3) {
ChatBubbleActivity.refreshList2(Mes);
} else {
}
handler.postDelayed(new Runnable() {
public void run() {
onHandleIntent();
}
}, 500);
}
@Override
protected void onHandleIntent(final Intent intent) {
httpIslemleri();
handler.postDelayed(new Runnable() {
public void run() {
onHandleIntent();
}
}, 500);
}
public void httpIslemleri() {
try {
Class.forName("net.sourceforge.jtds.jdbc.Driver");
try {
this.con = DriverManager.getConnection("Your DB String");
} catch (SQLException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
它现在不是免费的,但是这段代码仍然很乱,只需要一点点触摸,它就可以更好地工作。好编码!!