简体   繁体   中英

Android Weather app crashing-network error

I have been developing a weather app through Treehouse and unfortunately no one has been able to help me fix this perticular error.

For some reason no weather data is retrieved on the app. I signed up through forecast IO to get the weather data to the app but nothing appears and the app crashes.

I use my phone as an emulator but I receive no errors in the log. Only when I use the Android Studio emulator do I receive an error in the logcat. Any suggestions ?

Stormy app on gitHub Github

MainActivity.java file

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import butterknife.ButterKnife;
import butterknife.InjectView;

public class MainActivity extends ActionBarActivity {
public static final String TAG = MainActivity.class.getSimpleName();
    private CurrentWeather mCurrentWeather;

    @InjectView(R.id.timeLabel) TextView mTimeLabel;
    @InjectView(R.id.temperatureLabel) TextView mTemperatureLabel;
    @InjectView(R.id.humidityValue) TextView mHumidityValue;
    @InjectView(R.id.precipValue) TextView mPrecipValue;
    @InjectView(R.id.summaryLabel) TextView mSummaryLabel;
    @InjectView(R.id.iconImageView) ImageView mIconImageView;
    @InjectView(R.id.refreshImageView) ImageView mRefreshImageView;
    @InjectView(R.id.progressBar)ProgressBar mProgressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.inject(this);

        mProgressBar.setVisibility(View.INVISIBLE);

        final double latitude = 38.627;
        final double longitude = -90.199;

        mRefreshImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getForecast(latitude, longitude);
            }
        });


        getForecast(latitude, longitude);


        Log.d(TAG, "Main UI code is running!");

        }

    private void getForecast(double latitude, double longitude) {
        String apiKey = "8ec5f1674002ab5081cad28e9be10ced";
        String forecastUrl = "https://api.forecast.io/forecast/" + apiKey +
                "/" + latitude + "," + longitude;


        if(isNetworkAvailable()) {
            toggleRefresh();

            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(Request request, IOException e) {
                    toggleRefresh();
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            toggleRefresh();
                        }
                    });

                    alertUserAboutError();

                }

                @Override
                public void onResponse(Response response) throws IOException {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            toggleRefresh();
                        }
                    });
                    try {
                        String jsonData = response.body().string();
                        Log.v(TAG, response.body().string());
                        if (response.isSuccessful()) {
                            mCurrentWeather = getCurrentDetails(jsonData);
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    updateDisplay();
                                }
                            });
                            updateDisplay();
                        } else {
                            alertUserAboutError();
                        }
                    } catch (IOException e) {
                        Log.e(TAG, "Exception caught: ", e);
                    }
                      catch (JSONException e) {
                        Log.e(TAG, "Exception caught:", e);
                    }

                }

            });
        }
        else {
            Toast.makeText(this, getString(R.string.network_unavailable_message),
                    Toast.LENGTH_LONG).show();
        }
    }

    private void toggleRefresh() {
        if (mProgressBar.getVisibility() == View.INVISIBLE) {
            mProgressBar.setVisibility(View.VISIBLE);
            mRefreshImageView.setVisibility(View.INVISIBLE);
        } else {
            mRefreshImageView.setVisibility(View.INVISIBLE);
            mRefreshImageView.setVisibility(View.VISIBLE);
        }
    }

    private void updateDisplay() {
        mTemperatureLabel.setText(mCurrentWeather.getTemperature() + "");
        mTimeLabel.setText("At" + mCurrentWeather.getFormattedTime() + " it will be");
        mHumidityValue.setText(mCurrentWeather.getHumidity() + "");
        mPrecipValue.setText(mCurrentWeather.getPrecipChance() + "%");
        mSummaryLabel.setText(mCurrentWeather.getSummary());

        Drawable drawable = getResources().getDrawable(mCurrentWeather.getIconId());
        mIconImageView.setImageDrawable(drawable);
    }

    private CurrentWeather getCurrentDetails(String jsonData) throws JSONException {
            JSONObject forecast = new JSONObject(jsonData);
            String timezone = forecast.getString("timezone");
            Log.i(TAG, "From JSON:" + timezone);

            JSONObject currently = forecast.getJSONObject("currently");

            CurrentWeather currentWeather = new CurrentWeather();
            currentWeather.setHumidity(currently.getLong("time"));
            currentWeather.setTime(currently.getLong("time"));
            currentWeather.setIcon(currently.getString("icon"));
            currentWeather.setPrecipChance(currently.getDouble("precipProbability"));
            currentWeather.setTemperature(currently.getDouble("temperature"));
            currentWeather.setTimeZone(timezone);

            Log.d(TAG, currentWeather.getFormattedTime());

            return new CurrentWeather();
    }

    private boolean isNetworkAvailable() {
        ConnectivityManager manager = (ConnectivityManager)
                getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = manager.getActiveNetworkInfo();
        boolean isAvailable = false;
        if(networkInfo != null && networkInfo.isConnected()) {
         isAvailable = true;

        }
        return isAvailable;
    }

    private void alertUserAboutError() {
        AlertDialogFragment dialog = new AlertDialogFragment();
        dialog.show(getFragmentManager(), "error_dialog");
    }
}

"PropertyFetcher: AdbCommandRejectedException getting properties for device 0043d8b5c84ed1f5: device unauthorized.

Please check the confirmation dialog on your device."

Error log

02-10 14:17:31.130 52-52/? I/qemu-props﹕ received: qemu.hw.mainkeys=0
02-10 14:17:33.180 56-56/? I/SurfaceFlinger﹕ SurfaceFlinger's main thread ready to run. Initializing graphics H/W... 
02-10 14:18:51.060 624-624/? D/AndroidRuntime﹕ Calling main entry com.android.commands.pm.Pm 
02-10 14:19:01.630 548-548/com.android.launcher I/Choreographer﹕ Skipped 346 frames! The application may be doing too much work on its main thread. 
02-10 14:19:02.750 437-437/? I/Choreographer﹕ Skipped 1210 frames! The application may be doing too much work on its main thread. 
02-10 14:19:04.920 386-386/system_process W/BroadcastQueue﹕ Failure sending broadcast Intent { act=android.intent.action.TIME_TICK flg=0x50000014
(has extras) } android.os.TransactionTooLargeException 
at android.os.BinderProxy.transact(Native Method) 
at android.app.ApplicationThreadProxy.scheduleRegisteredReceiver(ApplicationThreadNative.java:1059)
at com.android.server.am.BroadcastQueue.performReceiveLocked(BroadcastQueue.java:421)
at com.android.server.am.BroadcastQueue.deliverToRegisteredReceiverLocked(BroadcastQueue.java:507)
at com.android.server.am.BroadcastQueue.processNextBroadcast(BroadcastQueue.java:714)
at com.android.server.am.ActivityManagerService.finishReceiver(ActivityManagerService.java:13807)
at android.content.BroadcastReceiver$PendingResult.sendFinished(BroadcastReceiver.java:419)
at android.content.BroadcastReceiver$PendingResult.finish(BroadcastReceiver.java:395)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:785)
at android.os.Handler.handleCallback(Handler.java:733) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:136) 
at com.android.server.ServerThread.initAndLoop(SystemServer.java:1093) 
at com.android.server.SystemServer.main(SystemServer.java:1179) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:515) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 
at dalvik.system.NativeStart.main(Native Method) 
02-10 14:19:08.800 386-386/system_process I/Choreographer﹕ Skipped 34 frames! The application may be doing too much work on its main thread. 
02-10 14:19:19.860 548-548/com.android.launcher I/Choreographer﹕ Skipped 1089 frames! The application may be doing too much work on its main thread. 
02-10 14:19:23.320 718-718/com.android.systemui I/Choreographer﹕ Skipped 679 frames! The application may be doing too much work on its main thread. 
02-10 14:19:25.100 718-718/com.android.systemui I/Choreographer﹕ Skipped 106 frames! The application may be doing too much work on its main thread. 
02-10 14:19:27.700 718-718/com.android.systemui I/Choreographer﹕ Skipped 154 frames! The application may be doing too much work on its main thread.
02-10 14:19:30.720 548-548/com.android.launcher I/Choreographer﹕ Skipped 61 frames! The application may be doing too much work on its main thread. 
02-10 14:19:57.300 893-893/? D/AndroidRuntime﹕ Calling main entry com.android.commands.am.Am 
02-10 14:19:57.400 386-398/system_process I/ActivityManager﹕ START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=aurielvilaire.com.stormy/.MainActivity} from pid 893 
02-10 14:19:57.890 386-714/system_process I/ActivityManager﹕ Start proc aurielvilaire.com.stormy for activity aurielvilaire.com.stormy/.MainActivity: pid=928 uid=10054 gids={50054, 3003} 
02-10 14:20:00.640 928-928/aurielvilaire.com.stormy D/MainActivity﹕ Main UI code is running! 
02-10 14:20:02.170 386-400/system_process I/ActivityManager﹕ Displayed aurielvilaire.com.stormy/.MainActivity: +4s339ms 
02-10 14:20:05.540 928-943/aurielvilaire.com.stormy D/MainActivity﹕ 1:20 PM 
02-10 14:20:05.600 928-943/aurielvilaire.com.stormy E/AndroidRuntime﹕ FATAL EXCEPTION: OkHttp Dispatcher Process: aurielvilaire.com.stormy, PID: 928 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.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 aurielvilaire.com.stormy.MainActivity.updateDisplay(MainActivity.java:154) 
at aurielvilaire.com.stormy.MainActivity.access$500(MainActivity.java:31)
at aurielvilaire.com.stormy.MainActivity$2.onResponse(MainActivity.java:122)
at com.squareup.okhttp.Call$AsyncCall.execute(Call.java:162) 
at com.squareup.okhttp.internal.NamedRunnable.run(NamedRunnable.java:33)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841) 
02-10 14:20:05.650 386-397/system_process W/ActivityManager﹕ Force finishing activity aurielvilaire.com.stormy/.MainActivity 
02-10 14:20:05.710 386-414/system_process W/InputDispatcher﹕ channel 'b20c7078 aurielvilaire.com.stormy/aurielvilaire.com.stormy.MainActivity (server)' ~ Consumer closed input channel or an error occurred. events=0x9 
02-10 14:20:05.710 386-414/system_process E/InputDispatcher﹕ channel 'b20c7078 aurielvilaire.com.stormy/aurielvilaire.com.stormy.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
02-10 14:20:05.720 386-606/system_process W/InputDispatcher﹕ Attempted to unregister already unregistered input channel 'b20c7078 aurielvilaire.com.stormy/aurielvilaire.com.stormy.MainActivity (server)' 
02-10 14:20:05.720 386-606/system_process I/WindowState﹕ WIN DEATH: Window{b20c7078 u0 aurielvilaire.com.stormy/aurielvilaire.com.stormy.MainActivity} 
02-10 14:20:05.960 386-397/system_process I/WindowManager﹕ Screenshot max retries 4 of Token{b2051338 ActivityRecord{b207d380 u0 aurielvilaire.com.stormy/.MainActivity t2 f}} appWin=Window{b20c7078 u0 aurielvilaire.com.stormy/aurielvilaire.com.stormy.MainActivity EXITING} drawState=4 
02-10 14:20:07.260 548-548/com.android.launcher I/Choreographer﹕ Skipped 59 frames! The application may be doing too much work on its main thread. 
02-10 14:20:08.550 386-400/system_process W/WindowManager﹕ This window was lost: Window{b20c7078 u0 aurielvilaire.com.stormy/aurielvilaire.com.stormy.MainActivity} 
02-10 14:20:08.550 386-400/system_process W/WindowManager﹕ mDisplayId=0 mSession=Session{b210e748 928:u0a10054} 
mClient=android.os.BinderProxy@b2116298 mOwnerUid=10054 
mShowToOwnerOnly=true package=aurielvilaire.com.stormy appop=NONE
mAttrs=WM.LayoutParams{(0,0)(fillxfill) sim=#120 ty=1 fl=#1810100
pfl=0x8 wanim=0x10302a1} Requested w=1080 h=1776 mLayoutSeq=71
mBaseLayer=21000 mSubLayer=0 mAnimLayer=21000+0=21000 mLastLayer=0
mToken=AppWindowToken{b208c460 token=Token{b2051338
ActivityRecord{b207d380 u0 aurielvilaire.com.stormy/.MainActivity
t2}}} mRootToken=AppWindowToken{b208c460 token=Token{b2051338
ActivityRecord{b207d380 u0 aurielvilaire.com.stormy/.MainActivity
t2}}} mAppToken=AppWindowToken{b208c460 token=Token{b2051338
ActivityRecord{b207d380 u0 aurielvilaire.com.stormy/.MainActivity
t2}}} mViewVisibility=0x0 mHaveFrame=true mObscured=true mSeq=0
mSystemUiVisibility=0x0 mPolicyVisibility=false
mPolicyVisibilityAfterAnim=false mAppOpVisibility=true
mAttachedHidden=false mGivenContentInsets=[0,0][0,0]
mGivenVisibleInsets=[0,0][0,0] mConfiguration={1.0 310mcc260mnc en_US
ldltr sw360dp w360dp h567dp 480dpi nrml port finger qwerty/v/v -nav/h
s.5} mHasSurface=true mShownFrame=[0.0,0.0][1080.0,1776.0]
isReadyForDisplay()=false mFrame=[0,0][1080,1776]
last=[0,0][1080,1776] mSystemDecorRect=[0,0][1080,1776]
last=[0,0][1080,1776] Frames: containing=[0,0][1080,1776]
parent=[0,0][1080,1776] display=[0,0][1080,1776]
overscan=[0,0][1080,1920] content=[0,75][1080,1776]
visible=[0,75][1080,1776] decor=[0,0][1080,1920] Cur insets:
overscan=[0,0][0,0] content=[0,75][0,0] visible=[0,75][0,0] Lst
insets: overscan=[0,0][0,0] content=[0,75][0,0] visible=[0,75][0,0]
WindowStateAnimator{b20db3d0
aurielvilaire.com.stormy/aurielvilaire.com.stormy.MainActivity}:
mSurface=Surface(name=aurielvilaire.com.stormy/aurielvilaire.com.stormy.MainActivity)
mDrawState=HAS_DRAWN mLastHidden=true Surface: shown=false layer=21005
alpha=0.0 rect=(0.0,0.0) 1080.0 x 1776.0 mShownAlpha=1.0 mAlpha=1.0
mLastAlpha=-1.0 mGlobalScale=1.0 mDsDx=1.0 mDtDx=0.0 mDsDy=0.0
mDtDy=1.0 mExiting=false mRemoveOnExit=false mDestroying=true
mRemoved=false 
02-10 14:20:52.610 386-606/system_process I/ActivityManager﹕ Start proc com.android.email for broadcast com.android.email/.service.EmailBroadcastReceiver: pid=1049 uid=10024 gids={50024, 3003, 1028, 1015} 
02-10 14:20:53.400 1049-1063/com.android.email D/ActivityThread﹕ Loading provider com.android.email.provider;com.android.email.notifier: com.android.email.provider.EmailProvider 
02-10 14:20:58.452 386-583/system_process W/ActivityManager﹕ Unable to start service Intent { cmp=com.android.email/.service.AttachmentDownloadService } U=0: not found 
02-10 14:20:58.522 1049-1103/com.android.email I/Email﹕Observing account changes for notifications 
02-10 14:20:58.622 386-432/system_process I/ActivityManager﹕ Start proc com.android.exchange for service com.android.exchange/.service.EmailSyncAdapterService: pid=1104 uid=10025 gids={50025, 3003, 1028, 1015} 
02-10 14:20:58.622 386-607/system_process W/ActivityManager﹕ Unable to start service Intent { cmp=com.android.email/.service.AttachmentDownloadService } U=0: not found 
02-10 14:20:58.882 1049-1065/com.android.email D/dalvikvm﹕ GC_FOR_ALLOC freed 313K, 16% free 3359K/3960K, paused 231ms, total 254ms 
02-10 14:21:49.352 718-718/com.android.systemui I/Choreographer﹕ Skipped 32 frames! The application may be doing too much work on its main thread.

After reading through that and looking at your code, I believe the main culprit here is that you are doing to much on the main thread. You should use the android AsyncTask to run especially network connections on a separate thread. For example you might use:

private class DownloadForecast extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {
      getForecast(); //run all your network intensive methods  
      return response;
    }

@Override
protected void onPostExecute(String result) {
  //update all your UI stuff.
}

Can't seem to correctly intent the code. But thats what you should use. Good luck.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM