Function not getting called right - java

I'm trying to call my updateDisplay method through a for loop to set the text for the corresponding index, but in the output only the 5th index code is getting run.
Here is the for loop that I'm calling in my fragment's onCreateView();
private int mIndexofDays;
for(int i =1; i < 6; i++) {
DateTime nextday = mDateTime.plusDays(i);
long time = nextday.getMillis() / 1000;
getForecast(mLattitude, mLongitude, time);
mIndexofDays = i;
}
Here is the getForecast() method:
private void getForecast(double latitude, double longitude, long time)
{
String apiKey = getResources().getString(R.string.api_key);
String forecastUrl = "https://api.forecast.io/forecast/" + apiKey +
"/" + latitude + "," + longitude + "," + time;
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(forecastUrl)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
}
#Override
public void onResponse(Call call, Response response) throws IOException {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
try {
String jsonData = response.body().string();
Log.v(TAG, jsonData);
if (response.isSuccessful()) {
mWeather = getCurrentDetails(jsonData);
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
Log.d(TAG, "Running....");
updateDisplay();
}
});
} else {
Log.d(TAG, "Response not successful");
}
} catch (IOException e) {
Log.e(TAG, " IOException caught: ", e);
} catch (JSONException e) {
Log.e(TAG, "JSON exception caught: ", e);
}
}
});
}
And here is the updateDisplay() method:
private void updateDisplay() {
if(mIndexofDays == 1) {
mDayOfWeek1.setText(mDateTime.plusDays(1).dayOfWeek().getAsShortText());
Drawable drawable = getResources().getDrawable(mWeather.getIconId());
mDayOfWeekImage1.setImageDrawable(drawable);
mHighTemp1.setText(mWeather.getTemperatureMax() + "");
mLowTemp1.setText(mWeather.getTemperatureMin() + "");
}
if(mIndexofDays == 2) {
mDayOfWeek2.setText(mDateTime.plusDays(2).dayOfWeek().getAsShortText());
Drawable drawable = getResources().getDrawable(mWeather.getIconId());
mDayOfWeekImage2.setImageDrawable(drawable);
mHighTemp2.setText(mWeather.getTemperatureMax() + "");
}
if(mIndexofDays == 3) {
mDayOfWeek3.setText(mDateTime.plusDays(3).dayOfWeek().getAsShortText());
Drawable drawable = getResources().getDrawable(mWeather.getIconId());
mDayOfWeekImage3.setImageDrawable(drawable);
mHighTemp3.setText(mWeather.getTemperatureMax() + "");
}
if(mIndexofDays == 4) {
mDayOfWeek4.setText(mDateTime.plusDays(4).dayOfWeek().getAsShortText());
Drawable drawable = getResources().getDrawable(mWeather.getIconId());
mDayOfWeekImage4.setImageDrawable(drawable);
mHighTemp4.setText(mWeather.getTemperatureMax() + "");
}
if(mIndexofDays == 5) {
mDayOfWeek5.setText(mDateTime.plusDays(5).dayOfWeek().getAsShortText());
Drawable drawable = getResources().getDrawable(mWeather.getIconId());
mDayOfWeekImage5.setImageDrawable(drawable);
mHighTemp5.setText(mWeather.getTemperatureMax() + "");
}
else
{
Log.d(TAG, "Index to high!!!");
}
}
From the logs I can see that "Running" is getting called but updateDisplay never updates for 1-4 indexes only for the 5th index.
I am a very novice programmer, so please tell me on what is wrong with my style and better methods to do what I'm trying to do.

modify updateDisplay and pass a copy of mIndexofDays as a parameter, and this should work. I can provide the actual implementation code but I encourage you to try it first yourself.
hope this helps :)

change your for loop like this
for(int i =1; i < 6; i++) {
mIndexofDays = i;
DateTime nextday = mDateTime.plusDays(i);
long time = nextday.getMillis() / 1000;
getForecast(mLattitude, mLongitude, time, mIndexofDays); // new parameter: mIndexofDays
}
catch the parameter mIndexofDays in getForecast method and pass it through updateDisplay method. Next, use the value of mIndexofDays to compare in your if...else statements. You can use Log method or time delay method to check if it's actually working or not.

Well, the issue is that your updateDisplay() is called only when you receive response in onResponse(). Now, by the time this happens your loop has already ended and the value of mIndexofDays is 5. To fix the issue one of the things you can do is to pass the value of mIndexofDays to your getForecast() method:
private void getForecast(double latitude, double longitude, long time, int indexOfDays) {
...
updateDisplay(numberOfDays);
...
}
You also need to change your updateDisplay() method:
private void updateDisplay(int indexOfDays) {
...
}
Also, get rid of the mIndexOfDays instance variable since you [probably] don't need it anywhere.

Related

The use of threads and async-tasks couldn't prevent ANR error

I'm having a huge problem for days. In fact, in my activity, I call an NTP server which I do using an async-task and I do multiple database operations(I'm using Firebase Database), and whenever this activity opens, there's an ANR error. I read that for long tasks, we should use a worker thread so I put the database operations in a thread but even with that, I still get an ANR error. What else do you suggest ?
(the NTP server returns the correct result and all the operations in database are done everytime, even though I get the ANR error.)
public class Start extends AppCompatActivity {
//declaring variables
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
new Thread(new Runnable() {
public void run(){
finishQuiz();
}
}).start();
final DatabaseReference myRef = FirebaseDatabase.getInstance().getReference();
myRef.addValueEventListener(new ValueEventListener() {
//in this part, I call getNetworkTime, and under specific conditions I set an intent AlarmManager
}
Here is the function finishQuiz() I call inside the thread :
public void finishQuiz() {
// DEFINING THE VARIABLES NEEDED
myRef.addListenerForSingleValueEvent( new ValueEventListener() {
String dateD, hourD, userID, nom, prenom;
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Date d = new Date();
timee = d.getTime();
try {
timee = new Start.getNetworkTime().execute().get();
} catch (Exception e) {
timee = d.getTime();
}
String dateD = dataSnapshot.child("quiz").child("dateD").getValue(String.class);
String hourD = dataSnapshot.child("quiz").child("heureD").getValue(String.class);
if (!(dateD.equals("")) && !(hourD.equals(""))) {
long nbQ = dataSnapshot.child("quiz").child("questions").getChildrenCount();
int dureeQ = Integer.valueOf(dataSnapshot.child("quiz").child("duree").getValue().toString());
String[] D = dateD.split("-", 3);
String[] H = hourD.split(":", 3);
Calendar calDebut = Calendar.getInstance();
calDebut.set(Integer.valueOf(D[2]), Integer.valueOf(D[1]) - 1, Integer.valueOf(D[0]), Integer.valueOf(H[0]), Integer.valueOf(H[1]), Integer.valueOf(H[2]));
Date dateDebutQ = calDebut.getTime();
long timeQFinInMillis = dateDebutQ.getTime() + (nbQ + 1) * dureeQ * 1000;
if (timee > timeQFinInMillis) {
try {
final SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm");
Calendar caldateQ = Calendar.getInstance();
String[] dateDT = dateD.split("-", 3);
String[] hourDT = hourD.split(":", 3);
caldateQ.set(Integer.valueOf(dateDT[2]), Integer.valueOf(dateDT[1]) - 1, Integer.valueOf(dateDT[0]), Integer.valueOf(hourDT[0]), Integer.valueOf(hourDT[1]), Integer.valueOf(hourDT[2]));
long c = caldateQ.getTimeInMillis();
List<Date> listPast = new ArrayList<>();
List<Date> listFuture = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.child("next quizs").getChildren()) {
String dateNext = ds.getKey();
try {
Date dateNx = formatter.parse(dateNext);
Date dateQQQ = caldateQ.getTime();
Date dateQQ = formatter.parse(formatter.format(dateQQQ));
long timeNx = dateNx.getTime();
if (timeNx < timee) {
listPast.add(dateNx);
}
else
{
listFuture.add(dateNx);
}
} catch (Exception e) {
}
}
for (int i = 0; i < listPast.size(); i++) {
myNextQuiz.child(formatter.format(listPast.get(i))).removeValue();
}
if (listFuture.size()==0) {
myQuiz.child("dateD").setValue("");
myQuiz.child("heureD").setValue("");
myQuiz.child("duree").setValue(10);
myQuiz.child("questions").setValue("This will be removed anyways");
} else
//I get ANR error in this case
{
Date minuD = listFuture.get(0);
for (int k = 1; k < listFuture.size(); k++) {
if ((listFuture.get(k).compareTo(minuD) < 0)) {
minuD = listFuture.get(k);
}
}
String date = formatter.format(minuD);
String[] DH = date.split(" ", 2);
myQuiz.child("dateD").setValue(DH[0]);
myQuiz.child("heureD").setValue(DH[1] + ":00");
String ddd = dataSnapshot.child("next quizs").child(date).child("duree").getValue().toString();
myQuiz.child("duree").setValue(ddd);
myQuiz.child("questions").removeValue();
int j = 1;
for (DataSnapshot ds : dataSnapshot.child("next quizs").child(date).child("questions").getChildren()) {
String quest = ds.child("question").getValue(String.class);
String sol = ds.child("sol").getValue(String.class);
String answA = ds.child("A").getValue(String.class);
String answB = ds.child("B").getValue(String.class);
String answC = ds.child("C").getValue(String.class);
String answD = ds.child("D").getValue(String.class);
myQuiz.child("questions").child("" + j).child("question").setValue(quest);
myQuiz.child("questions").child("" + j).child("sol").setValue(sol);
myQuiz.child("questions").child("" + j).child("A").setValue(answA);
myQuiz.child("questions").child("" + j).child("B").setValue(answB);
myQuiz.child("questions").child("" + j).child("C").setValue(answC);
myQuiz.child("questions").child("" + j).child("D").setValue(answD);
j++;
}
}
myPreQuiz.child(dateD + " " + hourD).child("dateD").setValue(dateD);
myPreQuiz.child(dateD + " " + hourD).child("heureD").setValue(hourD);
for (DataSnapshot ds : dataSnapshot.child("current quiz").child("number").getChildren()) {
userID = ds.getKey();
nom = dataSnapshot.child("utilisateurs").child(userID).child("Nom").getValue(String.class);
prenom = dataSnapshot.child("utilisateurs").child(userID).child("Prenom").getValue(String.class);
myPreQuiz.child(dateD + " " + hourD).child("gagnants").child(userID).setValue(nom + " " + prenom);
}
myCurrQuiz.child("currentQ").setValue("0");
myCurrQuiz.child("number").removeValue();
} catch (Exception e) {
//show Exception
} }}}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});}
And here's my async Task :
private class getNetworkTime extends AsyncTask<Void, Void, Long> {
#Override
protected Long doInBackground(Void... params) {
String TIME_SERVER = "2.android.pool.ntp.org";
try{
NTPUDPClient timeClient = new NTPUDPClient();
InetAddress inetAddress = InetAddress.getByName(TIME_SERVER);
TimeInfo timeInfo = timeClient.getTime(inetAddress);
long returnTime = timeInfo.getMessage().getTransmitTimeStamp().getTime(); //server time
return returnTime;
} catch (Exception e) {
Date d = new Date();
long l=d.getTime();
return l;
}
}
protected void onPostExecute(Long result) {
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
If it is helpful, before I use the NTP server, my code used to work perfectly, and I tested without the AlarmManager part and it worked fine too, and also, in the function finishQuiz(), as I mentioned in a comment, only that particular case gives the ANR error(which happens to be the most common case for my app), I mean without entering that block, there's no ANR error.
Even though you start executing your finishQuiz method on a background thread, the firebase callbacks are called back on the main (UI) thread. This is likely causing your ANR.
Try executing the code in the onDataChange() callback on a background thread.
new Thread(new Runnable() {
public void run(){
// PUT YOUR CODE FROM onDataChange() HERE, or use AsyncTask
}
}).start();
See this: Firebase Android: onDataChange() event always executed in Main UI Thread?

Waiting inside loop for the method to finish executing

I have a For loop in which I call a method to upload images to the server , the problem that i am facing that at a certain limit the server will force stop the opened socket so i have to upload every image at once
for (int i = 0; i < paths.size(); i++) {
transferData(paths.get(i), i);
}
and the transferData Function I am using the transfer Utility aws s3 function
TransferUtility transferUtility =
TransferUtility.builder()
.context(this)
.awsConfiguration(AWSMobileClient.getInstance().getConfiguration())
.s3Client(amazonS3Client)
.defaultBucket("name")
.build();
TransferObserver uploadObserver = transferUtility.upload("name", name, new File(path), CannedAccessControlList.PublicRead);
uploadObserver.setTransferListener(new TransferListener() {
#Override
public void onStateChanged(int id, TransferState state) {
Log.d(TAG, "onStateChanged: " + id + ", " + state);
if (TransferState.COMPLETED == state) {
}
}
#Override
public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
float percentDonef = ((float) bytesCurrent / (float) bytesTotal) * 100;
int percentage = (int) percentDonef;
Log.d(TAG, "onProgressChanged: " + percentage);
}
#Override
public void onError(int id, Exception ex) {
Log.e(TAG, "Error during upload: " + id, ex);
try {
showToast(ex.getMessage());
} catch (Exception e) {
e.printStackTrace();
}
ex.printStackTrace();
}
});
How to wait for the method to finish execution then continue the loop
to wait loop use this code :
CountDownLatch latch=new CountDownLatch(1);
for (int i = 0; i < paths.size(); i++) {
transferData(paths.get(i), i);
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
and put this at the end of your method that finished upload image or failed
latch.countDown();
when your method rich to latch.countDown(); your loop will be continue
notice that you must put your loop in another thread except main thread

Java Android modifies member variables from Callback thread

Basically, I am trying to get some value from the Api callback response, then assign those value to some of my member variables, but It seems like the program has to run over my getPatientRecord() method each time before it could go to my call, which I have never encountered before.
The Log output result is :
viewPatient: paitient method
viewPatient: secondHello worldnullnull
100SN9 - David Hello H M H 1971-08-09
This is my code:
public class ViewPatientRecord extends AppCompatActivity{
TextView tvName, tvGender, tvBirthDate, tvAddress;
String pGender, pAddress, pBirthdate;
String pName = "Hello world";
Patient myPatient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_patient_record);
tvName = findViewById(R.id.tvFullName);
tvGender = findViewById(R.id.tvGender);
tvBirthDate = findViewById(R.id.tvDb);
tvAddress = findViewById(R.id.tvAddress);
myPatient= new Patient();
try {
getPatientRecord();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void getPatientRecord() throws InterruptedException {
SharedPreferences myPre = getSharedPreferences("PatientRecord", MODE_PRIVATE);
if(myPre.getString("uuid",null)!=null){
retrievePatientByUuid(myPre.getString("uuid",null));
Log.d("viewPatient", "second"+pName+pGender+pBirthdate);
tvName.setText(pName);
tvGender.setText(pGender);
tvBirthDate.setText(pBirthdate);
tvAddress.setText(pAddress);
}else{
Toast.makeText(ViewPatientRecord.this, "Something went wrong, please contact the administrator for help!", Toast.LENGTH_SHORT).show();
}
}
private void retrievePatientByUuid(String uuid) throws InterruptedException {
RestApi api = RetrofitInstance.getRetrofitInstance().create(RestApi.class);
Log.d("viewPatient", "paitient method");
Call<Patient> call = api.getPatientByUUID(uuid, null);
call.enqueue(new Callback<Patient>() {
private volatile Patient obj = new Patient();
#Override
public void onResponse(Call<Patient> call, Response<Patient> response) {
if (response.body() != null) {
Patient patient = response.body();
if (patient != null) {
if (!patient.getDisplay().isEmpty()) {
pName = patient.getDisplay();
pGender = patient.getPerson().getGender();
pBirthdate = patient.getPerson().getBirthdate();
Log.d("viewPatient", pName.toString() + " H " + pGender.toString() + " H " + pBirthdate.toString() + " ?? ");
pAddress = "";
} else {
Log.d("viewPatient", "no results");
}
} else {
Toast.makeText(ViewPatientRecord.this, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(ViewPatientRecord.this, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<Patient> call, Throwable t) {
t.printStackTrace();
}
});
}
}
I don't see the problem. The call is done in retrievePatientByUuid which is called by getPatientRecord. So yes, you have to go through getPatientRecord. The call is async. It's in the callback that you should set your TextViews :
tvName.setText(pName);
tvGender.setText(pGender);
tvBirthDate.setText(pBirthdate);
tvAddress.setText(pAddress);

AsyncTask get String value output and store in mainthread variable

I'd like to get the string value output from AsyncTask. And store it into a variable on my main thread. How can I do so?
I tried to do store = new ReceiveData().execute().get() however it throws an execution exception error. But anyway, my question is not about the execution exception error. I just need a way to get the string out, please help!
Here is my activity code:
public class MainActivity extends AppCompatActivity { //MAIN ACTIVITIES (REMOTE)
double multiplier;
int seekbarvalue, finallumens;
#Override
protected void onCreate(Bundle savedInstanceState) {
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT); //On orientation change socket will disconnect...
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Toast.makeText(MainActivity.this, LoginActivity.SERVER_IP, Toast.LENGTH_LONG).show();
//================START AFTER DEFAULT ON CREATE=================
SeekBar seekbarbrightness = (SeekBar) findViewById(R.id.seekbarbrightness);
final TextView tblumens, tbvolts, tbamps;
tblumens = (TextView) findViewById(R.id.tblumens);
seekbarvalue = seekbarbrightness.getProgress();
multiplier = (double) seekbarvalue / 100;
finallumens = (int) (multiplier * LoginActivity.enterlumens);
tblumens.setText(String.valueOf(finallumens) + " Lumens");
tbvolts = (TextView) findViewById(R.id.tbvolts);
tbamps = (TextView) findViewById(R.id.tbamps);
seekbarbrightness.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekbarbrightness, int progress, boolean b) {
if (b == true) {
seekbarvalue = seekbarbrightness.getProgress();
multiplier = (double) seekbarvalue / 100;
finallumens = (int) (multiplier * LoginActivity.enterlumens);
tblumens.setText(String.valueOf(finallumens) + " Lumens");
if (LoginActivity.getSocket() != null) {
try {
LoginActivity.getSocket().getOutputStream().write(String.valueOf(multiplier).getBytes());
new ReceiveData().execute();
//infinite loop here to keep receiving volts and amperes.
//Do a split and assign value to volt and amp
//String[] strrecv= store.split("|");
//String volts = strrecv[0];
//String amps = strrecv[1];
//tbvolts.setText("Voltage: " + volts + " V");
//tbamps.setText("Amperes:" + amps + " A");
} catch (IOException e) {
e.printStackTrace();
}
} else {
Toast.makeText(MainActivity.this, "NOT connected To Socket, please disconnect and reconnect!", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
And in my Asynctask I am doing this.
class ReceiveData extends AsyncTask<Void, Void, String> {
String str;
protected String doInBackground(Void... args) {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(LoginActivity.getSocket().getInputStream()));
str = in.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
String str = "fail";
return str;
}
}
protected void onPostExecute(String str) {
//super.onPostExecute(str);
}
}
The purpose of AsyncTask is to perform asynchronous task in a separate thread to free the main thread and avoid UX issues. For your purpose, I suggest transferring all of the work inside your try block inside the AsyncTask and update the UI after execution.
Something like this
In MainThread
new ReceiveData().execute();
In AsyncTask
class ReceiveData extends AsyncTask<Void, Void, Boolean> {
String volts;
String amps;
protected Boolean doInBackground(Void... args) {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(LoginActivity.getSocket().getInputStream()));
str = in.readLine();
String[] strrecv= store.split("|");
volts = strrecv[0];
amps = strrecv[1];
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
protected void onPostExecute(Boolean result) {
if (result) {
tbvolts.setText("Voltage: " + volts + " V");
tbamps.setText("Amperes:" + amps + " A");
}
}
}
Note that this only works if your AsyncTask is defined inside your Activity. If not, you need to create an interface from the AsyncTask and implement it in your activity and activate it onPostExecute

Android "Only the original thread that created a view hierarchy can touch its views." error in Fragment [duplicate]

This question already has answers here:
Android "Only the original thread that created a view hierarchy can touch its views."
(33 answers)
Closed 5 years ago.
I've got this simple timer in my app which is runs in every 3 seconds.
It works perfectly if it's not in a fragment class.
But here in fragment I always got the error: Only the original thread that created a view hierarchy can touch its views.
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
String timeStamp = new SimpleDateFormat(
"yyyy.MM.dd HH:mm:ss").format(Calendar
.getInstance().getTime());
System.out.println("TimeStamp: " + timeStamp);
// Read And Write Register Sample
port = Integer.parseInt(gConstants.port);
String refe = "0";// HEX Address
ref = Integer.parseInt(refe, 16);// Hex to int
count = 10; // the number Address to read
SlaveAddr = 1;
astr = gConstants.ip; // Modbus Device
InetAddress addr;
try {
addr = InetAddress.getByName(astr);
con = new TCPMasterConnection(addr); // the
// connection
} catch (UnknownHostException e2) {
e2.printStackTrace();
}
// 1.Prepare the request
/************************************/
Rreq = new ReadMultipleRegistersRequest(ref, count);
Rres = new ReadMultipleRegistersResponse();
Rreq.setUnitID(SlaveAddr); // set Slave Address
Rres.setUnitID(SlaveAddr); // set Slave Address
// 2. Open the connection
con.setPort(port);
try {
con.connect();
System.out.println("Kapcsolódva!");
} catch (Exception e1) {
e1.printStackTrace();
}
con.setTimeout(2500);
// 3. Start Transaction
trans = new ModbusTCPTransaction(con);
trans.setRetries(5);
trans.setReconnecting(true);
trans.setRequest(Rreq);
try {
trans.execute();
} catch (ModbusIOException e) {
e.printStackTrace();
} catch (ModbusSlaveException e) {
e.printStackTrace();
} catch (ModbusException e) {
e.printStackTrace();
}
/* Print Response */
Rres = (ReadMultipleRegistersResponse) trans
.getResponse();
System.out.println("Connected to= " + astr
+ con.isConnected() + " / Start Register "
+ Integer.toHexString(ref));
count = 10;
for (int k = 0; k < count; k++) {
System.out.println("The value READ: "
+ Rres.getRegisterValue(k) + " "
+ Rres.getUnitID());
ki_adat = ki_adat + Rres.getRegisterValue(k) + "\n";
// Adatbázisba írás
ContentValues modbusData = new ContentValues();
modbusData.put("Value", Rres.getRegisterValue(k)); // tábla
// +
// érték
modbusData.put("timeStamp", timeStamp);
try {
gConstants.db.beginTransaction();
gConstants.db
.insert("Modbus", null, modbusData);
gConstants.db.setTransactionSuccessful();
} finally {
gConstants.db.endTransaction();
}
}
kiir.setText(ki_adat);
ki_adat = "";
}//run vége
}, 0, 3000);
This error occurs when trying to access UI elements from any thread that is not the UI thread.
To access/modify elements from a non-UI-thread, use runOnUIThread.
However as you need to change a UI element from within a fragment, runOnUIThread should be invoked onto the fragments owning activity. You can do this through getActivity().runOnUIThread().
EG:
timer.schedule(new TimerTask() {
#Override
public void run() {
// Your logic here...
// When you need to modify a UI element, do so on the UI thread.
// 'getActivity()' is required as this is being ran from a Fragment.
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
// This code will always run on the UI thread, therefore is safe to modify UI elements.
myTextBox.setText("my text");
}
});
}
}, 0, 3000); // End of your timer code.
For further information see the following documentation:
Android Fragments (specifically, getActivity()).
TimerTask.
Invoking a Runnable on the UI thread.
you need to use the runOnUIThread() function I have an example somwhere that I will post when I find it.
you need to give your timer an instance of MainActivity alternatively see this question I asked Android image timing issues with what sounds like a similar thing to what you were trying to do
public static void updateText(Activity act, resID)
{
loadingText = (TextView) activity.findViewById(R.id.loadingScreenTextView);
act.runOnUiThread(new Runnable()
{
public void run()
{
loadingText.setText(resID);
}
});
}
You are doing UI operation from another thread. I suggest you to use following.
runOnUiThread(new Runnable() {
#Override
public void run() {
kiir.setText(ki_adat);
}
2 solutions :
Use the View.post(Runnable) method
Use the Activity.post(Runnable) method
And put the myTextView.setText(str) call in the run() method of the Runnable object.
Try this:
textView.post(new Runnable() {
#Override
public void run() {
textView.setText("Hello!"); }
});
TRY THIS: put this part of code somewhere but not in activity onCreate method
public void LoadTable(final String u, final String k)
{
// runOnUiThread need to be used or error will appear
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
//method which was problematic and was casing a problem
createTable(u, k);
}
});
} catch (Exception exception) {
createAndShowDialog(exception, "Error");
}
return null;
}
}.execute();
}
Try this
new CountDownTimer(365*24*60*60, 3000) {
public void onTick(long millisUntilFinished) {
String timeStamp = new SimpleDateFormat(
"yyyy.MM.dd HH:mm:ss").format(Calendar
.getInstance().getTime());
System.out.println("TimeStamp: " + timeStamp);
// Read And Write Register Sample
port = Integer.parseInt(gConstants.port);
String refe = "0";// HEX Address
ref = Integer.parseInt(refe, 16);// Hex to int
count = 10; // the number Address to read
SlaveAddr = 1;
astr = gConstants.ip; // Modbus Device
InetAddress addr;
try {
addr = InetAddress.getByName(astr);
con = new TCPMasterConnection(addr); // the
// connection
} catch (UnknownHostException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
// 1.Prepare the request
/************************************/
Rreq = new ReadMultipleRegistersRequest(ref, count);
Rres = new ReadMultipleRegistersResponse();
Rreq.setUnitID(SlaveAddr); // set Slave Address
Rres.setUnitID(SlaveAddr); // set Slave Address
// 2. Open the connection
con.setPort(port);
try {
con.connect();
System.out.println("Kapcsolódva!");
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
con.setTimeout(2500);
// 3. Start Transaction
trans = new ModbusTCPTransaction(con);
trans.setRetries(5);
trans.setReconnecting(true);
trans.setRequest(Rreq);
try {
trans.execute();
} catch (ModbusIOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ModbusSlaveException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ModbusException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/* Print Response */
Rres = (ReadMultipleRegistersResponse) trans
.getResponse();
System.out.println("Connected to= " + astr
+ con.isConnected() + " / Start Register "
+ Integer.toHexString(ref));
count = 10;
for (int k = 0; k < count; k++) {
System.out.println("The value READ: "
+ Rres.getRegisterValue(k) + " "
+ Rres.getUnitID());
ki_adat = ki_adat + Rres.getRegisterValue(k) + "\n";
// Adatbázisba írás
ContentValues modbusData = new ContentValues();
modbusData.put("Value", Rres.getRegisterValue(k)); // tábla
// +
// érték
modbusData.put("timeStamp", timeStamp);
try {
gConstants.db.beginTransaction();
gConstants.db
.insert("Modbus", null, modbusData);
gConstants.db.setTransactionSuccessful();
} finally {
gConstants.db.endTransaction();
}
}
kiir.setText(ki_adat);
ki_adat = "";
}
public void onFinish() {}
}.start();

Categories

Resources