App works on emulators (and device via USB), but not when dwnloaded from GooglePlay store?

huangapple go评论77阅读模式
英文:

App works on emulators (and device via USB), but not when dwnloaded from GooglePlay store?

问题

抱歉,我无法提供大段的代码翻译,因为这样可能会导致版权问题。但我可以帮你提供代码中涉及的一些关键信息和问题解答。如果你有具体的问题或需要代码方面的帮助,请告诉我,我会尽力提供解答。

英文:

Apologies, I know there are similar questions on the forum already, but none of them seem to be quite the same issue as I'm running into here. I've just completed an Android tutorial course, and built and released my very first app - I'm a newbie so forgive me if I've done something stupid!

My app works fine on the laptop - on a variety of emulators, with a variety of SDK versions, and also works on a real device when plugged into the laptop with a USB cable. However, when I upload it onto the GooglePlay store (and wait 3 days for it to get reviewed!) it then doesn't work when I download it - onto the same device as was connected via USB.

The app crashes before the first page even opens, and the only error info I can get it the error info provided by GooglePlay - included below. The problem appears to be with my Parse Initialisation, but I don't know what or why? Any help would be much appreciated!

GOOGLEPLAY ERROR LOG:

java.lang.RuntimeException: 
  at android.app.ActivityThread.handleMakeApplication (ActivityThread.java:7041)
  at android.app.ActivityThread.handleBindApplication (ActivityThread.java:6989)
  at android.app.ActivityThread.access$1600 (ActivityThread.java:272)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2055)
  at android.os.Handler.dispatchMessage (Handler.java:107)
  at android.os.Looper.loop (Looper.java:237)
  at android.app.ActivityThread.main (ActivityThread.java:8016)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:493)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1076)
Caused by: java.lang.IllegalArgumentException: 
  at com.parse.ParseObjectSubclassingController.registerSubclass (ParseObjectSubclassingController.java:75)
  at com.parse.ParseObject.registerSubclass (ParseObject.java:491)
  at com.parse.ParseObject.registerParseSubclasses (ParseObject.java:3486)
  at com.parse.Parse.initialize (Parse.java:395)
  at com.baileycoding.StarterApplication.onCreate (StarterApplication.java:29)
  at android.app.Instrumentation.callApplicationOnCreate (Instrumentation.java:1190)
  at android.app.ActivityThread.handleMakeApplication (ActivityThread.java:7036)
  at android.app.ActivityThread.handleBindApplication (ActivityThread.java:6989)
  at android.app.ActivityThread.access$1600 (ActivityThread.java:272)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2055)
  at android.os.Handler.dispatchMessage (Handler.java:107)
  at android.os.Looper.loop (Looper.java:237)
  at android.app.ActivityThread.main (ActivityThread.java:8016)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:493)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1076)

APP MANIFEST.XML:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.baileycoding"
    android:targetSandboxVersion="1" >

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <application
        android:name="com.baileycoding.StarterApplication"
        android:allowBackup="true"
        android:usesCleartextTraffic="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.AppCompat.Light">
        <activity android:name="com.baileycoding.AboutActivity"></activity>
        <activity android:name="com.baileycoding.WineResult" />
        <activity android:name="com.baileycoding.MyResultsActivity" />
        <activity android:name="com.baileycoding.ScoreboardActivity" />
        <activity android:name="com.baileycoding.RatingActivity" />
        <activity android:name="com.baileycoding.GuessDescriptionActivity" />
        <activity android:name="com.baileycoding.GuessTastesActivity" />
        <activity android:name="com.baileycoding.GuessGrapeActivity" />
        <activity android:name="com.baileycoding.GuessCRVActivity" />
        <activity android:name="com.baileycoding.WineListActivity" />
        <activity android:name="com.baileycoding.StartGameActivity" />
        <activity android:name="com.baileycoding.WineAssignmentActivity" />
        <activity android:name="com.baileycoding.PrepActivity" />
        <activity android:name="com.baileycoding.WineInfoActivity2" />
        <activity
            android:name="com.baileycoding.WineInfoActivity"
            android:windowSoftInputMode="adjustPan" />
        <activity android:name="com.baileycoding.EventIdConfirmationActivity" />
        <activity
            android:name="com.baileycoding.CreateNewEventActivity"
            android:windowSoftInputMode="adjustPan" />
        <activity android:name="com.baileycoding.EventMenuActivity" />
        <activity android:name="com.baileycoding.InitialMenuActivity" />
        <activity
            android:name="com.baileycoding.MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <meta-data
            android:name="preloaded_fonts"
            android:resource="@array/preloaded_fonts" />
    </application>

</manifest>

BULD.GRADLE (module):

apply plugin: 'com.android.application'

android {
    compileSdkVersion 29
    buildToolsVersion '22.0.1'

    defaultConfig {
        applicationId "com.baileycoding.thegrapeunknown"
        minSdkVersion 26
        targetSdkVersion 29
        versionCode 2
        versionName '1.1'
        multiDexEnabled true
    }
    dexOptions {
        javaMaxHeapSize "4g"
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    compile 'com.android.support:appcompat-v7:26.0.0'
    compile 'com.parse.bolts:bolts-tasks:1.3.0'
    compile 'com.parse:parse-android:1.13.0'
    compile 'com.google.android.gms:play-services:9.4.0'
    compile 'com.android.support:multidex:1.0.0'
}

BUILD.GRADLE (project):

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    repositories {
        mavenCentral()
        jcenter()
        google()

    }
    dependencies {
        classpath 'com.android.tools.build:gradle:4.0.0'
    }
}

allprojects {
    repositories {
        mavenCentral()
        google()
    }
}

ext {
    compileSdkVersion = 22
    buildToolsVersion = "23.0.1"

    minSdkVersion = 9
    targetSdkVersion = 23
    defaultVersionCode = 1.1
}

PARSE STARTER ACTIVITY:

package com.baileycoding;

import android.app.Application;

import com.parse.Parse;
import com.parse.ParseACL;


public class StarterApplication extends Application {

  @Override
  public void onCreate() {
    super.onCreate();

    // Enable Local Datastore.
    Parse.enableLocalDatastore(this);

    // Add your initialization code here
    Parse.initialize(new Parse.Configuration.Builder(getApplicationContext())
            .applicationId("myappID")
            .clientKey("xxxxxxxxxxx") //hidden for security - let me know if useful to see
            .server("http://18.220.164.203/parse/")
            .build()
    );


    //PARSE SETUP STATEMENTS
    //ParseUser.enableAutomaticUser();

    ParseACL defaultACL = new ParseACL();
    defaultACL.setPublicReadAccess(true);
    defaultACL.setPublicWriteAccess(true);
    ParseACL.setDefaultACL(defaultACL, true);


  }
}

MAIN ACTIVITY. JAVA:

package com.baileycoding;

import android.content.Intent;
import android.os.Bundle;
import android.support.constraint.ConstraintLayout;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.parse.FindCallback;
import com.parse.LogInCallback;
import com.parse.ParseAnalytics;
import com.parse.ParseException;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import com.parse.ParseUser;
import com.parse.SignUpCallback;
import com.baileycoding.R;

import java.util.List;


public class MainActivity extends AppCompatActivity implements View.OnKeyListener, View.OnClickListener {

    EditText emailEditText;
    EditText passwordEditText;
    EditText nameEditText;
    Button loginButton;
    TextView switchTextView;
    ConstraintLayout backgroundLayout;

    Boolean loginMode; // 1 = signup, 0 = login
    String email;
    String password;
    String name;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setTheme(R.style.MyTheme);
        setContentView(R.layout.activity_main);

        //setTitle("Welcome");
        if (getSupportActionBar() != null) {
            getSupportActionBar().hide();
        }

        emailEditText = (EditText) findViewById(R.id.emailEditText);
        passwordEditText = (EditText) findViewById(R.id.passwordEditText);
        nameEditText = (EditText) findViewById(R.id.nameEditText);
        loginButton = (Button) findViewById(R.id.loginButton);
        switchTextView = (TextView) findViewById(R.id.switchTextView);
        backgroundLayout = findViewById(R.id.backgroundLayout);

        passwordEditText.setOnKeyListener(this);
        nameEditText.setOnKeyListener(this);
        backgroundLayout.setOnClickListener(this);

        loginMode = false;
        nameEditText.setVisibility(View.GONE);

        ParseQuery<ParseObject> query = ParseQuery.getQuery("User");
        query.whereNotEqualTo("username","test");
        query.findInBackground(new FindCallback<ParseObject>() {
            @Override
            public void done(List<ParseObject> objects, ParseException e) {
                if(e!=null || objects.size()==0){
                    Toast.makeText(MainActivity.this, "You are not currently logged in", Toast.LENGTH_SHORT).show();
                    if(e!=null){ e.printStackTrace();}
                } else {
                    if (ParseUser.getCurrentUser() != null) {
                        String currentUser = ParseUser.getCurrentUser().toString();
                        //ParseUser.logOut();
                        Toast.makeText(MainActivity.this, "Currently logged in as " + ParseUser.getCurrentUser().getUsername(), Toast.LENGTH_SHORT).show();
                        moveToInitialMenu();
                    }
                }
            }
        });


        ParseAnalytics.trackAppOpenedInBackground(getIntent());
    }

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {

        if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) {
            loginOrSignup(v);
        }
        return false;
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.backgroundLayout) {
            InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(getWindow().getDecorView().getRootView().getWindowToken(), 0);
        }
    }

    public void switchToSignup(View view) {

        if (loginMode == false) {
            loginMode = true;
            Log.i("Login mode switched to", "true; signup mode");
            loginButton.setText("SIGNUP");
            switchTextView.setText("Already have an account? Log in here");
            nameEditText.setVisibility(View.VISIBLE);
        } else {
            loginMode = false;
            Log.i("Login mode switched to", "false; login mode");
            loginButton.setText("LOGIN");
            switchTextView.setText("Don't have an account? Sign up here");
            nameEditText.setVisibility(View.GONE);
        }
    }

    public void loginOrSignup(View view) {
        loginButton.setEnabled(false);
        email = emailEditText.getText().toString();
        password = passwordEditText.getText().toString();
        name = nameEditText.getText().toString();

        if (loginMode) {
            if (email.matches("") || password.matches("") || name.matches("")) {
                Toast.makeText(this, "Please enter email, password and a display name", Toast.LENGTH_SHORT).show();
            } else {
                //SIGNUP USER
                ParseUser user = new ParseUser();
                user.setUsername(email);
                user.setPassword(password);
                user.put("displayName", name);
                user.signUpInBackground(new SignUpCallback() {
                    @Override
                    public void done(ParseException e) {
                        if (e == null) {
                            Toast.makeText(MainActivity.this, "Successfully created new user", Toast.LENGTH_SHORT).show();
                            moveToInitialMenu();
                        } else {
                            e.printStackTrace();
                            Toast.makeText(MainActivity.this, "Sign Up failed: " + e.getMessage(), Toast.LENGTH_LONG).show();
                            loginButton.setEnabled(true);
                        }
                    }
                });
            }
        } else {
            if (email.matches("") || password.matches("")) {
                Toast.makeText(this, "Please enter email and password", Toast.LENGTH_SHORT).show();
            } else {
                //LOGIN USER
                ParseUser.logInInBackground(email, password, new LogInCallback() {
                    @Override
                    public void done(ParseUser user, ParseException e) {
                        if (e == null) {
                            Toast.makeText(MainActivity.this, "Login successful", Toast.LENGTH_SHORT).show();
                            moveToInitialMenu();
                        } else {
                          loginButton.setEnabled(true);
                          e.printStackTrace();
                            Toast.makeText(MainActivity.this, "Login failed: " + e.getMessage(), Toast.LENGTH_LONG).show();
                        }
                    }
                });
            }
        }


    }

    public void moveToInitialMenu() {
        Intent intent = new Intent(getApplicationContext(), InitialMenuActivity.class);
        startActivity(intent);
    }

}

MAIN ACTIVITY.XML:


<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/backgroundLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:background="@drawable/backgroundv1"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/loginButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:fontFamily="@font/delius"
        android:onClick="loginOrSignup"
        android:paddingLeft="20dp"
        android:paddingRight="20dp"
        android:text="LOG IN"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.495"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/nameEditText" />

    <EditText
        android:id="@+id/emailEditText"
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="290dp"
        android:ems="10"
        android:fontFamily="@font/delius"
        android:hint="Email address"
        android:inputType="textEmailAddress"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.502"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/passwordEditText"
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:ems="10"
        android:fontFamily="@font/delius"
        android:hint="Password"
        android:inputType="textPassword"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.502"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/emailEditText" />

    <EditText
        android:id="@+id/nameEditText"
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:ems="10"
        android:fontFamily="@font/delius"
        android:hint="Name (to display to others)"
        android:inputType="textPersonName"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/passwordEditText" />


    <TextView
        android:id="@+id/switchTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:fontFamily="@font/delius"
        android:onClick="switchToSignup"
        android:text="Don't have an account yet? Sign up here instead"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.495"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/loginButton" />
</android.support.constraint.ConstraintLayout>

答案1

得分: 1

在调试中设置 minifyEnabled 为 true。也许 minifyEnabled 移除了一些不应该移除的代码。因为在模拟器上似乎运行正常。然后在本地调试代码。

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    debug {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
英文:

Set minifyEnabled true in debug. Maybe minifyEnabled removed some code that it shouldn't. Since it seems to work fine on emulator. And then debug the code locally.

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    debug {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

huangapple
  • 本文由 发表于 2020年8月20日 21:47:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/63506509.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定