The program closes after executing the loop on Thread [duplicate] - java

This question already has answers here:
Android update TextView in Thread and Runnable
(4 answers)
Unfortunately MyApp has stopped. How can I solve this?
(23 answers)
Closed 11 months ago.
Error only when i use editText.setText(sbz); What to do? Without Thread, setText works good
public void onstart(View view) {
setContentView(R.layout.activity_main);
EditText editText = (EditText)findViewById(R.id.result);
Toast.makeText(this, "LOG FINISH!", Toast.LENGTH_SHORT).show();
String str = new String((String) textView1.getText());
StringBuilder sbz = new StringBuilder();
new Thread(() -> {
int x = 0;
while(x<100) {
x++;
sbz.append(str);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
editText.setText(sbz);
}).start();

Try stringBuffer instead of stringbuilder. Stringbuilder is not syncronized.

editText.setText from your Thread is trying to modify an android view from a background thread, this is a forbidden action. You should only modify android views from the UI/Main thread. In your example, you can try posting it to the UI thread
public void onstart(View view) {
setContentView(R.layout.activity_main);
EditText editText = (EditText)findViewById(R.id.result);
Toast.makeText(this, "LOG FINISH!", Toast.LENGTH_SHORT).show();
String str = new String((String) textView1.getText());
StringBuilder sbz = new StringBuilder();
new Thread(() -> {
int x = 0;
while(x<100) {
x++;
sbz.append(str);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
editText.post(() -> {
editText.setText(sbz)
});
}).start();

Related

Send string from thread bluetooth service to textView in main activity

I want to send value from string (distance to obstacle) to my TextView in main activity.
I tried to use Handler, but still not working (crash) or receive nothing.
A part code which receive data from HC-05 (screen where you see in debug value assignet to variable)
enter image description here
#Override
public void run() {
byte[] buffer = new byte[1024];
int bytes;
while(true){
try {
bytes = inputStream.read(buffer);
final String comingMsg = new String(buffer,0,bytes);
Log.d(TAG,"InputStream: " + comingMsg);
/*mHandler2.post(new Runnable() {
#Override
public void run() {
Message message = new Message();
message.obj = comingMsg;
mHandler2.sendMessage(message);
}
});*/
}catch (IOException e){
Log.e(TAG,"Write: Error reading input." + e.getMessage());
active=false;
break;
}
}
}
Here It's parts of code from MainActivity where I tried put something to get values from service.
[I add, that for this moment i want to see something values from bluetooth in textView. Later I want to create parse string and send custom text to custom TextView - example: FL: (Front Left)- to one textView, FR: (Front Right) - to second textView]
There is method implementThreads(), because I wanted to do 6 Threads to 6 TextView which every time is refreshing value from string in Services (there I tried get value from Bluetooth Service)
Log.d(TAG,"Check intent - result");
if(getIntent().getIntExtra("result",0)==RESULT_OK){
mDevice = getIntent().getExtras().getParcelable("bonded device");
myBluetoothService = new MyBluetoothService(getApplicationContext());
startConnection(mDevice,MY_UUID);
Log.d(TAG,"Check is active service");
checkIfActive();
}
Log.d(TAG,"Check intent - connect_to_paired");
if(getIntent().getIntExtra("connect_to_paired",0)==RESULT_OK){
mDevice = getIntent().getExtras().getParcelable("bonded_paired_device");
myBluetoothService = new MyBluetoothService(getApplicationContext());
startConnection(mDevice,MY_UUID);
Log.d(TAG,"Check is active service");
checkIfActive();
}
}
#Override
public void onStart(){
super.onStart();
myBluetoothService = new MyBluetoothService(getApplicationContext());
}
public void checkIfActive(){
Log.d(TAG,"CheckIfActive: Started");
if(myBluetoothService.active){
Log.d(TAG,"CheckIfActive: Running method implementThreads()");
implementThreads();
}
}
public void implementThreads(){
Log.d(TAG,"ImplementThreads: Started");
Thread thread = new Thread(){
#Override
public void run() {
try{
sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
}
};
thread.start();
}
public void startConnection(BluetoothDevice device,UUID uuid){
Log.d(TAG,"StartConnection: Initializing connection");
myBluetoothService.startClient(device,uuid);
}
Thanks all for help, because It's very important for me !
Use this to interect with UI Thread for operations like updating textviews etc.
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
//YOUR CODE HERE
Message message = new Message();
message.obj = comingMsg;
mHandler2.sendMessage(message);
}
});

One timer, multiple intents

I'm working on an app, where you have multiple cardviews on when you click on them it shows you a intro then after 10 seconds redirects to you to the activity, but i only know how to do one, but with multiple activities idk how to do that.
heres de code
TextView textView = findViewById(R.id.textView);
textView.setText(getIntent().getStringExtra("param"));
Animation myamin = AnimationUtils.loadAnimation(this, R.anim.transition);
textView.startAnimation(myamin);
final Intent a = new Intent(this, phonensmar.class);
Thread timer = new Thread()
{
public void run()
{
try
{
sleep(3000);
}catch (InterruptedException e)
{
e.printStackTrace();
}
finally {
startActivity(a);
finish();
}
}
};
timer.start();

Application Stop when input editText more than 10 digit

i am trying to show calculation textView(txtHasil) it is running but when input more than 10 application suddenly force close. this is my code:
btnHitung.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//String plafond = NumberTextWatcherForThousand.trimCommaOfString(edtPlafond.getText().toString());
String plafond = edtPlafond.getText().toString().trim();
String jasa = edtJasa.getText().toString().trim();
int edtPlafond = Integer.parseInt(plafond);
float edtJasa = Float.parseFloat(jasa);
double hasil = (edtPlafond * edtJasa )/100;
txtHasil.setText(""+hasil+"\nplafond: "+edtPlafond+"\nJasa: "+edtJasa);
//txtHasil.addTextChangedListener(new NumberTextWatcherForThousand((EditText) txtHasil));
}
}
i have been try change int,float, and double. i have been read this link: This program doesn't work properly for decimals more than 10 digits? but didn't help. any suggest will be help. thanks
Integer.parseInt(plafond);
This is the problem.It can not parse anythong larger than Integer.MAX_VALUE
int edtPlafond;
try {
edtPlafond = Integer.parseInt(plafond);
} catch (NumberFormatException e ) {
e.printStackTrace();
// add proper error handling
}
The best would be to have a longer value - long...
long edtPlafond;
try {
edtPlafond = Long.parseLong(plafond);
} catch (NumberFormatException e ) {
e.printStackTrace();
// add proper error handling
}
And an example of handling the error in a better way, by displaying the error in a dialog:
} catch (NumberFormatException e ) {
new AlertDialog.Builder(getActivity())
.setTitle("Error: incorrect number entered!")
.setMessage("The exact error is: " + e.getMessage())
.setPositiveButton("Ok",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int b) {
dialog.cancel();
}
});
.create()
.show();
}
Note: all conversions need such a treatment...

android: Variable in runOnUiThread

Hi i m using Android Studio, and I am using Deprecated function in a runOnUiThread
It forces me to use a a Final Variable inside the runOnUiThread
this is ok for the new function but for the Deprecated function i get an error
Error:(133, 16) error: incompatible types
required: Thread
found: void
anyone can help to fix this.
Thread thread = new Thread() {
public void run() {
try {
String sURL = "http://pollsdb.com/schlogger/223.png";
URL url = null;
url = new URL(sURL);
assert url != null;
Bitmap bmp = null;
bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
bmp = Bitmap.createScaledBitmap(bmp, 200, 200, false);
BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), bmp);
final BitmapDrawable fbmpdw = bitmapDrawable;
runOnUiThread(new Runnable() {
#Override
public void run() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
ib1.setBackground(fbmpdw);
} else {
ib1.setBackgroundDrawable(fbmpdw); // <---- this the problem
}
}
});
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
your problem is not the setBackgroudDrawable method, but Thread.start(), which returns nothing (void), while you are trying to assign its return value to the thread local variable
You can both change Thread thread = new Thread() { ... } and then call thread.start() or simply new Thread() { ... }.start(); without assignment
Do you need to use the thread variable anywhere else? I don't think you need to.
If so, simply change in your first line
Thread thread = new Thread() {
To
new Thread() {
Your .start() will return void, and you cannot do Thread thread=//some thing void as it is expecting some Thread type.

Listing of the Network Devices in Android

Similar or the same Question has been answered here
I am creating an Android App, which sends a broadcast message to the network and prepares a list of devices responding back.
Now What I did:
I created an Activity Class DeviceManagerWindow.java which calls a thread Sender.java.
Sender.java is responsible for sending the broadcast message.
Then the DeviceManagerWindow.java calls another thread which is responsible for listening to the devices responding back. The devices responding back will be listed in the Activity as soon as the device responds back. For that I have a TableLayout named deviceList.
What code I have written:
DeviceManagerWindow.java This method is called when a button for search is pressed
public void searchDevice(View v) throws IOException, InterruptedException
{
//Log.v("TableLayout:",view.toString());
sendMulticastFlyport = new Thread(new FlyportSender(MAC));
sendMulticastFlyport.start();
new Thread()
{
public void run()
{
MulticastSocket socketComputer=null;
try
{
socketComputer = new MulticastSocket(WifiConstants.COMPUTER_RECV_PORT);
socketComputer.joinGroup(InetAddress.getByName(WifiConstants.COMPUTER_NETWORK_ADDR));
socketComputer.setSoTimeout(1*60*1000);
byte[] inBufComputer = new byte[1024];
DatagramPacket inPacketComputer = new DatagramPacket(inBufComputer, inBufComputer.length);
while(true)
{
System.out.println("Listening...");
socketComputer.receive(inPacketComputer);
System.out.println("Received");
String msg = new String(inBufComputer, 0, inPacketComputer.getLength());
DeviceInformation device = new DeviceInformation(1, msg, inPacketComputer.getAddress().toString());
addDevice(device, false, 1);
Log.v("Received:","Received Computer From :" + inPacketComputer.getAddress() + " Msg : " + msg);
//System.out.write(inPacket.getData(),0,inPacket.getLength());
System.out.println();
Thread.sleep(2000);
}
}
catch(Exception e)
{
Log.v("Exception:","During Receiving Computer: "+e.toString());
try
{
addDevice(null, true, 1);
}
catch (IOException e1)
{
Log.v("Exception:", "Computer End Error: " +e1);
}
}
finally
{
socketComputer.close();
}
}
}.start();
The following code creates a list:
public void addDevice(DeviceInformation device, boolean bool, int type) throws IOException
{
TableLayout tb = (TableLayout) findViewById(R.id.DeviceList);
Log.v("addDevice","Called");
if(bool)
{
LayoutParams layout = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
TableRow tr = new TableRow(getApplicationContext());
TextView tv = new TextView(getApplicationContext());
System.out.println(tb);
tv.setLayoutParams(layout);
tr.setLayoutParams(layout);
String message;
Log.v("addDevice","Device Timeout");
switch(type)
{
case 1:
computerEnd=true;
break;
case 2:
raspberryEnd=true;
break;
case 3:
flyportEnd=true;
break;
}
if(computerEnd && raspberryEnd && flyportEnd)
{
if(rowCounter>0)
{
message = "No More Devices";
}
else
{
message = "No Devices Found";
}
tv.setText(message);
tv.setTextColor(Color.WHITE);
if(rowCounter%2==0)
{
tr.setBackgroundColor(Color.DKGRAY);
}
else
{
tr.setBackgroundColor(Color.GRAY);
}
tv.setVisibility(1);
tr.addView(tv);
tb.addView(tr);
}
}
else
{
LayoutParams layout = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
TableRow tr = new TableRow(getApplicationContext());
TextView tv = new TextView(getApplicationContext());
tv.setLayoutParams(layout);
tr.setLayoutParams(layout);
Log.v("addDevice","Received");
String textToDisplay = device.getDeviceTypeString()+"\n"+device.getIPAddress(); //Write the text to display
tv.setText(textToDisplay);
tv.setTextColor(Color.WHITE);
Drawable img;
if(device.getDeviceType()==1)
{
img = getApplicationContext().getResources().getDrawable(R.drawable.pc);
}
else if(device.getDeviceType()==2)
{
img = getApplicationContext().getResources().getDrawable(R.drawable.raspberry);
}
else
{
img = getApplicationContext().getResources().getDrawable(R.drawable.flyport);
}
img.setBounds(0,0,70,45);
tv.setCompoundDrawables(null, null, img, null);
tv.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
}
});
if(rowCounter%2==0)
{
tr.setBackgroundColor(Color.DKGRAY);
}
else
{
tr.setBackgroundColor(Color.GRAY);
}
rowCounter++;
Log.v("Result","Device Added");
}
}
Now it is showing me an error in the logCat as:
05-11 22:01:10.165: E/AndroidRuntime(13873): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
What I have figured out from this is only the UIThread is allowed to access the Views that is created.
Previously I had tried:
new Thread()
{
public void run()
{
runOnUiThread(){
MulticastSocket socketComputer=null;
try
{
....
....
....
}
}
And that time I received an error:
Main thread cannot access Network
Before that I had tried to use synchronized methods which was called from the Receiving.java Thread File. but It also gave an error of not creating the list.
I have tried all possible ways.
Now what whould I do.?
You figured it out right. Now you can learn to either use a Handler to pass information to the UI thread (see http://www.techotopia.com/index.php/A_Basic_Overview_of_Android_Threads_and_Thread_handlers) or AsyncTask (see http://developer.android.com/reference/android/os/AsyncTask.html).
I personally prefer AsyncTask. You can paste the code which performs the search into the doInBackground() method (not need to use a separate thread, doInBackground() already does that for you) and paste the UI-related code (the list creation code) into the onPostExecute() method. Search for further examples of AsyncTask if it is not sufficiently clear how it works from the link.
EDIT: If you intend your device search code to run indefinitely, then you have to resort to Handler, as AsyncTask expects the doInBackground() method to finish before running onPostExecute(). See which option better suits your needs.

Categories

Resources