We're working in an android app with the 4 version and we need a mysql connection. We are doing this with a php file which returns the data base result. The following code are working because if we debug the project we can see the correct database result in the the System.out.println. line.
But, if we try to change one text in our app for the result of the database our app can’t run correctly and the error was in the t.setText(txt); line.
Can anybody help me with this problem? Do you have another idea to do the database connection or is it the correct way?
Thanks a lot.
My code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//FUNCIONA NO BORRAR
final httpHandler handler = new httpHandler();
Thread thread = new Thread()
{
#Override
public void run() {
try {
if(true) {
sleep(1000);
String txt = handler.post("http://www.golftipp.com/pruebas_android/app.php");
TextView t = (TextView) findViewById(R.id.textView2);
t.setText(txt);
System.out.println(txt);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
}
The error
05-30 02:42:50.331 1276-1291/es.softline.connexiodb.app E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-87
Process: es.softline.connexiodb.app, PID: 1276
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6094)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:824)
at android.view.View.requestLayout(View.java:16431)
at android.view.View.requestLayout(View.java:16431)
at android.view.View.requestLayout(View.java:16431)
at android.view.View.requestLayout(View.java:16431)
at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:352)
at android.view.View.requestLayout(View.java:16431)
at android.widget.TextView.checkForRelayout(TextView.java:6600)
at android.widget.TextView.setText(TextView.java:3813)
at android.widget.TextView.setText(TextView.java:3671)
at android.widget.TextView.setText(TextView.java:3646)
at es.softline.connexiodb.app.MainActivity$1.run(MainActivity.java:33)
Non-UI threads cannot access views, use runOnUiThread():
Thread thread = new Thread()
{
#Override
public void run() {
try {
if(true) {
sleep(1000);
String txt = handler.post("http://www.golftipp.com/pruebas_android/app.php");
TextView t = (TextView) findViewById(R.id.textView2);
runOnUiThread(new Runnable() {
#Override
public void run() {
// do UI updates here
t.setText(txt);
}
});
System.out.println(txt);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
Related
How to add our own image via java code to the image view. I use ImageUri to set the Image to Image View.
ImageView carView = root.findViewById(R.id.carview);
if (car.registeredCarsArray.containsKey(logins)){
String[] carImage = car.registeredCarsArray.get(logins).getCarImageArray();
for (int i = 0; ; i++) {
try {
sleep (1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
carView.setImageURI(Uri.parse(carImage[i%4]));
}
}
here activity not starting.(because of infinite for-loop). So, I tried Thread instead of using this in oncreate() function.
new Thread(new Runnable() {
#Override
public void run() {
ImageView carView = root.findViewById(R.id.carview);
if (car.registeredCarsArray.containsKey(logins)){
String[] carImage = car.registeredCarsArray.get(logins).getCarImageArray();
for (int i = 0; ; i++) {
try {
sleep (1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
carView.setImageURI(Uri.parse(carImage[i%4]));
}
}
}
}).start();
then I got this error :(
E/AndroidRuntime: FATAL EXCEPTION: Thread-3
Process: com.example.cardock, PID: 3599
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:8191)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1420)
I am getting the following error in my android studio. Is there any way I can solve this issue. Its causing a lot of crashes in my app.
E/AndroidRuntime: FATAL EXCEPTION: Firebase-Messaging-Intent-Handle
Process: com.cnlcabs.cnldrivers, PID: 19224
java.lang.RuntimeException: Can't create handler inside thread Thread[Firebase-Messaging-Intent-Handle,5,main] that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:227)
at android.os.Handler.<init>(Handler.java:129)
at com.cnlcabs.cnldrivers.data.MyFirebaseMessagingService.stopPlayer(MyFirebaseMessagingService.java:264)
at com.cnlcabs.cnldrivers.data.MyFirebaseMessagingService.onMessageReceived(MyFirebaseMessagingService.java:233)
at com.google.firebase.messaging.FirebaseMessagingService.dispatchMessage(com.google.firebase:firebase-messaging##21.1.0:13)
at com.google.firebase.messaging.FirebaseMessagingService.passMessageIntentToSdk(com.google.firebase:firebase-messaging##21.1.0:8)
at com.google.firebase.messaging.FirebaseMessagingService.handleMessageIntent(com.google.firebase:firebase-messaging##21.1.0:3)
at com.google.firebase.messaging.FirebaseMessagingService.handleIntent(com.google.firebase:firebase-messaging##21.1.0:3)
at com.google.firebase.messaging.EnhancedIntentService.lambda$processIntent$0$EnhancedIntentService(com.google.firebase:firebase-messaging##21.1.0:1)
at com.google.firebase.messaging.EnhancedIntentService$$Lambda$0.run(Unknown Source:6)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at com.google.android.gms.common.util.concurrent.zza.run(com.google.android.gms:play-services-basement##17.5.0:6)
at java.lang.Thread.run(Thread.java:923)
my code for myfirebasemessagingservice line 264 is
private void stopPlayer() {
try {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
if (NotificationReceiverSoundPlay.mPlayer != null)
NotificationReceiverSoundPlay.mPlayer.stop();
}
}, 2000);
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
You need to run these lines in UI thread not in a separate thread. Like this answer.
new Handler().postDelayed(new Runnable() {
activity.runOnUiThread(new Runnable() {
public void run() {
if (NotificationReceiverSoundPlay.mPlayer != null)
NotificationReceiverSoundPlay.mPlayer.stop();
}
});
}, 2000);
This question already has answers here:
android.content.res.Resources$NotFoundException: String resource ID #0x0
(8 answers)
Closed 6 years ago.
I need a thread that waits some time then changes a text in a TextView.
My search found how to use runOnUiThread
I understood the first answer and tried to use it in my code but I get an error when calling setText in the thread.
Here is my code
(start is the onClick function of a button):
public class MainActivity extends AppCompatActivity {
public int i = 0;
private TextView mText;
private Thread thread;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mText = (TextView)findViewById(R.id.text);
}
public void start (View v) {
runThread();
}
private void runThread() {
new Thread() {
public void run() {
while (true) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
i++;
mText.setText((i));
}
});
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}
Here is my error
09-26 20:26:34.054 22254-22254/com.horizon.testtimerthread E/AndroidRuntime: FATAL EXCEPTION: main
android.content.res.Resources$NotFoundException: String resource ID #0x1
at android.content.res.Resources.getText(Resources.java:1058)
at android.support.v7.widget.ResourcesWrapper.getText(ResourcesWrapper.java:52)
at android.widget.TextView.setText(TextView.java:3866)
at com.horizon.testtimerthread.MainActivity$1$1.run(MainActivity.java:39)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:177)
at android.app.ActivityThread.main(ActivityThread.java:4947)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
at dalvik.system.NativeStart.main(Native Method)
Thank you in advance for your help.
mText.setText((i)) is the problem.
Android thinks that you are referencing a String ID and is crashing because it cannot find a String with an ID of 1. If you meant to set the text to "1", "2" ect... then write mText.setText((Integer.toString(i)))
Since i has type int, you are calling setText(int resourceId) variant of function, what is obvious not you want. setText(String.valueOf(i)) should work.
After user William suggest me to change my code for showing interstitial ad to this
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//setDebugMode(true);
initialiseAccelerometer();
interstitial = new InterstitialAd(this);
interstitial.setAdUnitId(getResources().getString(R.string.InterstitialAd_unit_id));
interstitial.setAdListener(new AdListener() {
public void onAdClosed() {
// Create another ad request.
final AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
interstitial.loadAd(adRequest);
}
});
// Create ad request.
final AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
interstitial.loadAd(adRequest);
}
and for showing ad this:
public synchronized void GameOver() {
if (lives_left > 0) {
//success! - game passed - save score
ScoreManager.save_localscore_simple(score_times[currentLevel], "" + currentLevel, false);
if (Level_Buttons.length >= currentLevel + 1)
ScoreManager.save_localscore_simple(unlocked, "unlock" + (currentLevel + 1));
if (sound_success != 0 && !sound_muted)
sp.play(sound_success, 1, 1, 0, 0, 1);
//open interstitial ad
if (interstitial.isLoaded()) {
interstitial.show();
}
} else {
//game not passed
if (sound_gameover != 0 && !sound_muted)
sp.play(sound_gameover, 1, 1, 0, 0, 1);
}
//open interstitial ad
if (interstitial.isLoaded()) {
interstitial.show();
}
StopMusic();
state = GAMEOVER;
}
On every gameover in game I get this error:
W/dalvikvm(20469): threadid=11: thread exiting with uncaught exception (group=0x4180bda0)
E/AndroidRuntime(20469): FATAL EXCEPTION: Thread-67543
E/AndroidRuntime(20469): Process: com.test.mygame, PID: 20469
E/AndroidRuntime(20469): java.lang.IllegalStateException: isLoaded must be called on the main UI thread.
E/AndroidRuntime(20469): at com.google.android.gms.common.internal.bh.b(SourceFile:251)
E/AndroidRuntime(20469): at com.google.android.gms.ads.internal.b.e(SourceFile:345)
E/AndroidRuntime(20469): at com.google.android.gms.ads.internal.client.m.onTransact(SourceFile:66)
E/AndroidRuntime(20469): at android.os.Binder.transact(Binder.java:361)
E/AndroidRuntime(20469): at com.google.android.gms.internal.ap$a$a.isReady(Unknown Source)
E/AndroidRuntime(20469): at com.google.android.gms.internal.au.isLoaded(Unknown Source)
E/AndroidRuntime(20469): at com.google.android.gms.ads.InterstitialAd.isLoaded(Unknown Source)
E/AndroidRuntime(20469): at com.test.mygame.MainGame.GameOver(MainGame.java:1128)
E/AndroidRuntime(20469): at com.test.mygame.MainGame.Step(MainGame.java:773)
E/AndroidRuntime(20469): at com.test.nudge.Screen.run(Screen.java:207)
E/AndroidRuntime(20469): at java.lang.Thread.run(Thread.java:841)
What is wrong here? Please explain me simple as possible because I`m newbie without any programming knowledge before :) Thanks!
This is maybe not the full answer, but It´s hard to say the right answer because it´s not clear from Your code above. You´ve not showed where You use GameOver(), but I think You called it in the wrong place, I think You call it in any background thread because inside GameOver You call interstitial.isLoaded() which causing Your problem. Like the stacktrace said, call it in the main ui thread. For exqample, call this inside Your GameOver():
runOnUiThread(new Runnable() {
#Override public void run() {
if (interstitial.isLoaded()) {
interstitial.show();
}
}
});
Possibly You have to call it with an activity reference, it depends from where Do You call GameOver():
mYourActivity.runOnUiThread(new Runnable() {
#Override public void run() {
if (interstitial.isLoaded()) {
interstitial.show();
}
}
});
Share my case and solution.
I did new thread and call isLoaded(). It got this same error.
So that I solve it by below code using Messager.
Hope this help.
Code as below.
Main thread:
public void onCreate() {
mHandler = new Handler(Looper.getMainLooper()) {
#Override
public void handleMessage(Message message) {
switch (message.what) {
case ACTION_ADMOB_IS_LOADED:
MainActivity.logForDebug(TAG,"AdMob : Check for loaded");
if(mIAds.isLoaded()) {
MainActivity.logForDebug(TAG,"AdMob : Loaded ...... OK");
mIAds.show();
}
break;
}
}
};
}
Other thread
public void run(){
while(true){
Message message;
// ------ For AdMob ------
Message message = mHandler.obtainMessage(ACTION_ADMOB_IS_LOADED,null);
message.sendToTarget();
}
}
I have created 2 threads in my android app but they don't work :(.
final Thread t1 = new Thread() {
// #Override
public void run() {
camera.takePicture(null, null, photoCallback);
Log.e("mediafile", mediaFile+"");
}
};
t1.start();
final Thread t2 = new Thread() {
// #Override
public void run() {
Intent myIntent = new Intent(CameraActivity.this, ModificationActivity.class);
Log.e("le chemin de la photo", "" + mediaFile);
myIntent.putExtra("imagePath", ""+mediaFile);
startActivity(myIntent);
}
};
try {
t1.join();
t2.start();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
My variable is always at null when I start my intent because the first thread is not finished.
I hope you can help me :D
Thanks in advance to all
This is the log :
11-05 14:29:59.936 18216-18216/com.mcm.citadium I/Choreographer﹕ Skipped 72 frames! The application may be doing too much work on its main thread. 11-05 14:30:05.140 18216-18387/com.mcm.citadium E/mediafile﹕ null 11-05 14:30:05.148 18216-18389/com.mcm.citadium E/le chemin de la photo﹕ null 11-05 14:30:05.652 18216-18216/com.mcm.citadium E/fin de photoCallback﹕ /storage/sdcard0/Pictures/MyCameraApp/IMG_20131105_143005.jpg
Well, first of all you don't need to create any threads to capture image - you can run camera.takePicture on main thread safely - it will handle its job in another thread anyway (see documentation).
So, for example you could trigger picture-taking activity in your button onClick handler :
shootButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCamera.takePicture(null, null, photoCallback);
}
});
Your photoCallback would then look something like :
Camera.PictureCallback photoCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
// generate file path for new picture
String fileName = "myPicture.jpg";
String mediafile = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
.getCanonicalPath() + "/mydir/" + fileName;
// launching new activity to modify picture
Intent myIntent = new Intent(CameraActivity.this,
ModificationActivity.class);
Log.e("le chemin de la photo", "" + mediaFile);
myIntent.putExtra("imagePath", ""+mediaFile);
startActivity(myIntent);
}
};
I think you can use [Handler]: http://developer.android.com/reference/android/os/Handler.html
to schedule the two thread.
Some examples :
http://androidexample.com/Thread_With_Handlers_-_Android_Example/index.php?view=article_discription&aid=58&aaid=83
http://examples.javacodegeeks.com/android/core/os/handler/android-handler-example/
Or [AsyncTask]: http://developer.android.com/reference/android/os/AsyncTask.html which is almost equal to " Handler + Thread + Message + ThreadPool "
Some examples :
http://examples.javacodegeeks.com/android/core/os/asynctask/android-asynctask-example/
AsyncTask Android example
Why is the starting of t2 inside the try-catch? I think if you simply place both starts outside of the try-catch, and then join both threads in it, this should work.
t1.start();
t2.start();
try {
t1.join();
t2.join();
}
catch (Exception e) { e.printStackTrace(); }