在我的应用程序中,我正在使用Intentservice从服务器获取数据,并将获取的数据存储到本地sqlite db中。我正在使用5
IntentService来获取并填充五个表。每个意向服务的数据最多可包含300行。我该怎么办?
IntentService代码:
public class SendBpRecordServer extends IntentService {
DbHelper dbHelper;
public static final String TAG="BP Service";
public JSONObject finalData;
public SendBpRecordServer() {
super("BP");
dbHelper=new DbHelper(this);
Log.i("In Constructor",TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
String recName=intent.getStringExtra("nameTag");
if (recName.equals("fetch"))
{
Log.i("Send Data","Yes");
fetchDatFromServer();
ResultReceiver resultReceiver=intent.getParcelableExtra("receiverTagBP");
Log.d("BP Reseult ",resultReceiver.toString());
Bundle bun= new Bundle();
bun.putBoolean("Process_Complete_bp",true);
resultReceiver.send(2, bun);
}
else {
Log.i("Inside Service PUT BP ","Yes");
dataCollected();
}
}
private void fetchDatFromServer() {
Response.Listener listener=new Response.Listener<JSONObject>()
{
@Override
public void onResponse(JSONObject response) {
Log.i("Json Array Response", response.toString());
try
{
Boolean responseStatusCondition=response.getBoolean("success");
if (responseStatusCondition)
{
JSONArray jsonArray=response.getJSONArray("response");
Log.i("Array Size is",Integer.toString(jsonArray.length()));
for (int i=0;i<jsonArray.length();i++)
{
JSONObject childJSONObject = jsonArray.getJSONObject(i);
//Set the flag bit to 1 since data is already at server
long result=dbHelper.insertIntoBloodPressureDetails(childJSONObject.getInt("systolic"), childJSONObject.getInt("diastolic"), childJSONObject.getLong("timestamp"),1 );
// Log.i("Insertion result ",Long.toString(result));
}
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
//This is midnight time in GMT
long unixTimeStamp = c.getTimeInMillis();
//Convert it in to Indian time System
long indianMidNightTime=unixTimeStamp-19800000;
//Log.i("Now Calculates Days","doing");
dbHelper.calculateDays(dbHelper.bpTableName, dbHelper.bpCOLUMN_days, dbHelper.bpCOLUMN_timestamp, indianMidNightTime);
}
}catch (JSONException js)
{
js.printStackTrace();
}
}
};
Response.ErrorListener errorListener=new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
NetworkResponse response = error.networkResponse;
// Handle Error
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
error.printStackTrace();
Toast.makeText(getApplicationContext(), " this Network Error", Toast.LENGTH_SHORT).show();
} else if (error instanceof AuthFailureError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "User not authorized", Toast.LENGTH_SHORT).show();
} else if (error instanceof ServerError && response != null)
{
try {
String res = new String(response.data,
HttpHeaderParser.parseCharset(response.headers, "utf-8"));
// Now you can use any deserializer to make sense of data
JSONObject obj = new JSONObject();
obj.put("New Error",res);
Log.i("New Server Error",obj.toString());
} catch (UnsupportedEncodingException e1) {
// Couldn't properly decode data to string
e1.printStackTrace();
} catch (JSONException e2) {
// returned data is not JSONObject?
e2.printStackTrace();
}
} else if (error instanceof NetworkError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "Network Error", Toast.LENGTH_SHORT).show();
} else if (error instanceof ParseError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "Error consuming request", Toast.LENGTH_SHORT).show();
}
else error.printStackTrace();
}
};
String bp_url=Constants.url+"bp";
JsonObjectHeader customRequest=new JsonObjectHeader(bp_url, null, listener, errorListener);
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(customRequest);
}
private void dataCollected() {
JSONArray jsonArray=new JSONArray();
ArrayList<Graph> arrayList=dbHelper.fetchDataFromBp();
for (int i=0;i<arrayList.size();i++)
{
Graph graph=new Graph();
graph=arrayList.get(i);
try {
JSONObject jsonObject=new JSONObject();
jsonObject.put("systolic",graph.getHeight());
jsonObject.put("diastolic",graph.getWeight());
jsonObject.put("timestamp",graph.getTime());
jsonArray.put(jsonObject);
}catch (JSONException js)
{
js.printStackTrace();
}
}
finalData=new JSONObject();
try {
finalData.put("bp",jsonArray);
}catch (JSONException js)
{
js.printStackTrace();
}
sendDatatoServer();
}
private void sendDatatoServer()
{
Response.Listener listener=new Response.Listener<JSONObject>()
{
@Override
public void onResponse(JSONObject response) {
try {
// Parsing json object response
// response will be a json object
//Toast.makeText(getApplicationContext(),response.toString(),Toast.LENGTH_LONG).show();
Boolean responseStatusCondition = response.getBoolean("success");
Log.i("Response BP",responseStatusCondition.toString());
if (responseStatusCondition)
dbHelper.setTheFlagBpTable();
else
Log.i("Something Went Wrong"," On Server");
}
catch (JSONException k)
{
Log.i("On Response",k.getMessage());
k.printStackTrace();
}
}
};
Response.ErrorListener errorListener=new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// Handle Error
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
error.printStackTrace();
Toast.makeText(getApplicationContext(), " this Network Error", Toast.LENGTH_SHORT).show();
} else if (error instanceof AuthFailureError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "User not authorized", Toast.LENGTH_SHORT).show();
} else if (error instanceof ServerError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "Server error", Toast.LENGTH_SHORT).show();
} else if (error instanceof NetworkError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "Network Error", Toast.LENGTH_SHORT).show();
} else if (error instanceof ParseError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "Error consuming request", Toast.LENGTH_SHORT).show();
}
else error.printStackTrace();
}
};
Log.i("Bp Final Data",finalData.toString());
JsonObjectHeader customRequest=new JsonObjectHeader(Request.Method.PUT, Constants.url+"bp", finalData, listener, errorListener);
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(customRequest);
}
}
调用intentservice的代码:
Log.i("Fetch BP Data ", SendBpRecordServer.TAG);
resultReceiverBP=new MyResultReceiver(new Handler());
resultReceiverBP.setReceiver(this);
Log.i("Bp resultreceiver ",resultReceiverBP.toString());
Intent intent2=new Intent(this,SendBpRecordServer.class);
intent2.putExtra("nameTag","fetch");
intent2.putExtra("receiverTagBP",resultReceiverBP);
startService(intent2);
并在完成任务时向我发送代码
在onReceiveResult
..中,结果代码通过调用的intentservice发送,并且当计数达到5时,就启动mainactivity(尽管此技巧不起作用,即在未完成分配给intentservice的任务的情况下启动mainactivity)。
@Override
public void onReceiveResult(int resultCode, Bundle resultData) {
// TODO Auto-generated method stub
Log.d("Diabetes","received result from Service= "+resultData.getString("ServiceTag"));
// Log.d("BMI ","received result from Service= "+resultData.getString("ServiceTag"));
/* if (progressDialog.isShowing()) {
progressDialog.dismiss();
}*/
Log.i("Get Values ",Integer.toString(Constants.getValues));
if (resultCode==0 && resultData.getBoolean("Process_Complete"))
Constants.getValues++;
if (resultCode==1 && resultData.getBoolean("Process_Complete_bmi"))
Constants.getValues++;
if (resultCode==2 && resultData.getBoolean("Process_Complete_bp"))
Constants.getValues++;
if (resultCode==3 && resultData.getBoolean("Process_Complete_med_stats"))
Constants.getValues++;
if (resultCode==4 && resultData.getBoolean("Process_Complete_one"))
Constants.getValues++;
if (Constants.getValues==5)
{
Constants.getValues=0;
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
startActivity(new Intent(this,MainActivity.class));
finish();
}
}
您是否绝对确定IntentService
是UI冻结的根本原因?意向服务是专门设计用于在工作线程中运行的,以便从主(UI)线程中卸载处理,其主要原因之一是有助于
防止 UI冻结。
也许尝试在UI级别开始调试工作。特别地,要提供ResultReceiver
的IntentService
,当你启动它,你怎么在做onReceiveResult
该接收器实例回调方法?
除此之外,对于您遇到冻结的活动,请检查您要执行哪种操作。Loader
UI冻结的一个常见原因是至少从我的经验来看,这是导致UI冻结的主要原因,这是在主线程上从数据库加载大量数据(即,不使用或类似方法将处理卸载到工作线程)。
更新资料
我想我已经解决了问题所在。有两个主要问题,都取决于您如何使用Volley。将请求添加到Volley队列时,该请求将异步执行。这意味着该queue
方法将立即返回。在您的意图服务代码中,这意味着该服务立即继续告知ResultReceiver
它已完成处理,而实际上它所完成的只是将请求排队。所有五个Intent服务都将执行此操作,这意味着MainActivity
将很快输入该内容。这是第一个问题。
第二个问题说明了您遇到的冻结问题。尽管Volley在工作线程上执行请求,但它返回对主线程上请求的已解析响应-
请参阅此处的文档。这意味着您在意向服务中正在执行的所有响应处理(将数据放入数据库等)实际上都在主(UI)线程上进行。这解释了冻结。
您可能想要在此处执行的操作改为改用Volley’s
RequestFuture
。通过允许您阻止直到请求完成,这基本上将异步请求转换为同步请求。为此,请创建一个适当类型的Future(JSONObject
在您的情况下),并将其设置为请求的侦听器和错误侦听器。然后,像现在一样对请求进行排队,然后在以后立即调用get
将来的方法。该方法将阻塞,直到响应完成处理为止。可以在意图服务中执行此操作,因为它在工作线程而不是UI线程上运行。
如果请求成功,您将获得返回的数据,并且可以执行当前在Response.Listener
实现中的所有逻辑。如果发生错误(即,由于某种原因请求失败),将来的请求将引发异常,您可以处理该异常以采取任何适当的措施。
使用请求期货是与使用侦听器的完全不同的方法,您可能需要对代码进行大量更改才能使其正常工作,但是它应该可以解决您遇到的问题。
希望能对您有所帮助,我诚挚的歉意不提早发现此错误。
我正在开发一个用于指纹读取器的Android应用程序,我的操作包括验证用户指纹(连续),以及注册新指纹(从Web API获取指纹)。我正在使用Morpho MSO 1300指纹读取器。 当我运行我的应用程序时,我不断收到以下logcat消息 01-02 11:19:48.910 5286-11417/com.cms.attendance D/dalvikvm: GC_FOR_ALLOC释放 293
当我运行任何JavaFX代码(甚至是hello world http://docs.oracle.com/JavaFX/2/get_started/hello_world.htm)并按下capslock键时,应用程序将冻结,直到关闭caps lock为止。 我在Kubuntu12.04中运行JavaFX,可能是Kubuntu的bug,我没有机会在另一个操作系统上尝试。 知道吗?
问题内容: 美好的一天, 我有一个ServerSocket的无限循环,工作正常…问题是当我尝试使用按钮启动ServerSocket时。我的用户界面“冻结”什么都没有动,但服务器正常运行,这里有一个 ScreenShot : http://i.gyazo.com/15d331166dd3f651fc7bda4e3670be4d.png 当我按下按钮“ Iniciar”表示启动服务器时,用户界面冻结(
8.1.1 程序的用户界面 界面是指两个体系之间的分界与接合部分,例如人-机界面、水-油界面等。在程序设计领域,一个程序的用户界面(user interface,简称 UI)指的是程序中与用户进行交互的部 分,用户通过 UI 向程序输入数据或者请求程序执行特定任务,而程序通过 UI 向用户显示各 种信息。 如果程序员写的程序是自用的,那么用户界面是怎样的并不重要,因为程序员完全了解 程序的行为,能
我试图更新层的QgsProject实例与计时器在一个新的线程,并显示更新的数据在QMain Window.但是无论我如何改变属性/特性/层,它总是冻结应用程序。我知道QgisProject存在于主线程中,所以是否有可能在不冻结应用程序的情况下更改一个层?如果是怎样? 下面的代码是我试图在一个额外的线程中做的。
我尝试使用Quarkus制作一个原生应用程序,但当我构建它时,它冻结了: > 我在Manjaro linux下,用github存储库安装了graalvm。