无法启动服务

时间:2019-04-06 02:03:46

标签: android android-service

我正在尝试启动服务,但出现错误。 我不知道如何解决这个特定的问题。 我正在上课的班级:

package com.example.test;

public class Purchase extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_purchase);
        final Intent i = new Intent(this,MyHostApduService.class);
        Livedate<User> user = *something*;
        user.observe(Purchase.this, new Observer<User>() {
            @Override
            public void onChanged(@Nullable User user) {
                i.putExtra("user name", user.getUserName());
                i.putExtra("credit card", user.getCreditCard());
                i.putExtra("context", Purchase.class);
                i.putExtra("mail", user.getMail());
            }
        });
        Toast.makeText(Purchase.this, "YOU CAN ONLY MAKE A PURCHASE AFTER GETTING CLOSE TO THE OTHER DEVICE", Toast.LENGTH_SHORT).show();
        this.startService(i);
    }

}

服务:

public int onStartCommand(Intent intent, int flags, int startId) {
    creditCard = intent.getExtras().getString("credit card");
    return START_STICKY;
}

错误:

java.lang.RuntimeException: Unable to start service com.example.test.MyHostApduService@fe81f37 with Intent { cmp=com.example.test/.MyHostApduService }: 
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference

3 个答案:

答案 0 :(得分:0)

问题::在“购买”活动中,启动MyHostApduService服务时,您没有在意图上加任何额外的内容,这就是为什么总会出现NullPointerException的原因。

解决方案::从您的代码中,我想您想先启动服务,每当用户在活动中发生更改时,便希望将用户送至服务中心进行处理。

步骤1:更改User类以实现Parcelable接口。

public class User implements Parcelable {
    private String userName;
    private String creditCard;
    private String mail;

    public User() {
    }

    protected User(Parcel in) {
        userName = in.readString();
        creditCard = in.readString();
        mail = in.readString();
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getCreditCard() {
        return creditCard;
    }

    public void setCreditCard(String creditCard) {
        this.creditCard = creditCard;
    }

    public String getMail() {
        return mail;
    }

    public void setMail(String mail) {
        this.mail = mail;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(userName);
        dest.writeString(creditCard);
        dest.writeString(mail);
    }

    public static final Creator<User> CREATOR = new Creator<User>() {
        @Override
        public User createFromParcel(Parcel in) {
            return new User(in);
        }

        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };
}

步骤2:更改活动中的代码

user.observe(Purchase.this, new Observer<User>() {
    @Override
    public void onChanged(@Nullable User user) {
        i.putExtra("user", user);
        Purchase.this.startService(i);
    }
});

步骤3:更改服务中的代码。

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    user = intent.getParcelableExtra("user");
    if (user == null) {
        // The first time this service is started, user is not change yet.
    } else {
        // The next time this service is started, user is changed.
        Log.i("TAG", user.getCreditCard() + "");
    }
    return START_STICKY;
}

答案 1 :(得分:0)

您要传递给服务的意图没有属性“信用卡”。这是因为您启动服务时的意图是空的(没有其他功能)。仅在LiveData发生更改时才执行代码i.putExtra("credit card", user.getCreditCard());。当活动首次开始时,没有任何东西触发LiveData的onChanged。

答案 2 :(得分:0)

我建议在这里阅读有关事件循环的内容,如果您搜索“ android事件循环”,那么这里有一些不错的文章。

有效地是,您的方法“ onCreate”和“ onChanged”都是回调。 “ onCreate”将在“ onChanged”开始之前完全执行。这意味着您在不带任何参数的情况下启动服务会得到空指针异常。通常,如果可以避免,您不想跨多个回调使用对象。

解决此问题的一种可能方法是在收到新数据时启动服务。但是请注意,如果可以对用户数据进行多次更改,会发生什么情况。

package com.example.test;

public class Purchase extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_purchase);
        Livedate<User> user = *something*;
        user.observe(Purchase.this, new Observer<User>() {
            @Override
            public void onChanged(@Nullable User user) {
                final Intent i = new Intent(this,MyHostApduService.class);
                i.putExtra("user name", user.getUserName());
                i.putExtra("credit card", user.getCreditCard());
                i.putExtra("context", Purchase.class);
                i.putExtra("mail", user.getMail());
                Purchase.this.startService(i);
                Toast...
            }
        });
    }
}