从适配器启动活动

时间:2018-04-05 09:40:15

标签: java android android-recyclerview nullpointerexception

我正在开发一个应用程序,当用户从回收站视图中进行选择时,该应用程序从服务器下载数据。我已经在主要活动中的异步任务中获取了要下载和解析的数据。这工作正常,但下载完成后我想开始一个新的活动来显示下载的数据,这就是我的问题所在。

public GetItems(String username, Context context, Activity activity) {
    this.username = username;
    this.context = context;
    this.activity = activity;
}   

上面是我的异步任务的构造函数。我从我的Recyclerview的OnClicklistener传递了这些值。

@Override
protected void onPostExecute(Void aVoid) {
    super.onPostExecute(aVoid);
    try {           
        //This is where the error lays
        activity.startActivity( new Intent(activity,BasketActivity.class));
    }        
} catch (Exception e) {
    Log.e(tag,e.toString());
}

问题出在哪里,我尝试过类似问题的许多不同答案,但没有一个有帮助。目前我收到以下错误

  

java.lang.NullPointerException:尝试调用虚方法' java.lang.String android.content.Context.getPackageName()'在空对象引用上

holder.itemView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Toast.makeText(mContext,holder.basketName.getText().toString(),Toast.LENGTH_SHORT).show();
        setBasketName(holder.basketName.getText().toString());
        MainActivity Activity = new MainActivity();
        mainActivity.new GetBasketItems(getUsername(),getImei(),getBasketName(),mContext,mActivity).execute();

    }
});

以上是我的OnClickListener,我将值传递给异步任务,我尝试同时使用上下文和活动,并且每个人都获得NullPointerException时间。

8 个答案:

答案 0 :(得分:2)

更改此

activity.startActivity(new Intent(activity,BasketActivity.class));

 context .startActivity( new Intent(context,BasketActivity.class));

或者在适配器中创建asynck任务。

答案 1 :(得分:1)

最好的方法是使用回调而不是在构造函数上传递活动。

您只需创建一个界面,如:

 public interface OnNextActivityListener {
        public void nextActivityClickEvent();
    }

此回调应该是构造函数Adapter上的参数,当您单击itemView时,它应该如下所示:

holder.itemView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
       callback.nextActivityClickEvent();
    }
});

在您的活动中实施您的界面:

public class YourActivity extends ActionBarActivity implements OnNextActivityListener {
....

//don't forget to add on your adapter constructor "this" as a parameter

   @Override
    public void nextActivityClickEvent(String url) {
        activity.startActivity( new Intent(YourActivity.this,BasketActivity.class)); 
    }
}

这是处理适配器内部操作的最佳做​​法。

答案 2 :(得分:1)

试试这个: 创建如下界面:

public interface SuccessfulDownloadListener {
    void navigateToNewActivity(PfizerMessage message);
}

为您的活动实现接口,并在Activity类中为此接口创建一个对象:

//declare the variable
private SuccessfulDownloadListener downloadListner;

//initialize the variable in onCreate()
downloadListner = new SuccessfulDownloadListener();

@Override
void navigateToNewActivity(PfizerMessage message){
    startActivity( new Intent(this, BasketActivity.class));
}

将此接口对象传递给Adapter构造函数:

new RecyclerAdapter(..other parameters.., this)

你的适配器将是

//declare the variable
private SuccessfulDownloadListener downloadListner;

//constructor
RecyclerAdapter(..other parameters.., SuccessfulDownloadListener downloadlistener){
    this.downloadListner = downloadListner;
}

@Override
protected void onPostExecute(Void aVoid) {
    super.onPostExecute(aVoid);
    try {           
        //This is where the error lays
        downloadListner.navigateToNewActivity();
    } catch (Exception e) {
    Log.e(tag,e.toString());
    }
}

答案 3 :(得分:0)

你得到一个空指针异常,因为在Android中你不应该保持对活动的引用,这些活动可能随时被系统破坏。 要完成您正在尝试的内容,您应首先阅读AsyncTask以及如何使用它。一旦理解,您只需实例化一个并从MyActivity执行它:

 new DownloadFilesTask().execute();

一旦执行,你就可以将流回到你的帖子中执行:

protected void onPostExecute(Long result) {
     nowShowDownloadedData();
 }

并且调用 nowShowDownloadedData()返回到您的原始活动,因此此时您可以通常的方式打开新活动,将此活动作为上下文传递。

注意:异步任务在您的调用者活动中被定义为私有类,因此它可以访问它。

答案 4 :(得分:0)

尝试添加标志

Intent in=new Intent(context,NextActivity.class);
in.addFlags(FLAG_ACTIVITY_NEW_TASK);
context.startActivity(in);

希望这会起作用

答案 5 :(得分:0)

尝试以下

Intent intent=new Intent(holder.itemView.getContext(),NewActivity.class);
holder.itemView.getContext().startActivity(intent);

答案 6 :(得分:0)

Crete适配器,用于保存带有getter和setter的解析数据

node

并将数据添加到adpter

public class DataAdapter implements Serializable { }

使用Bundle

将列表传递给下一个活动
List<DataAdapter> adpter= new ArrayList<DataAdapter>();
adpter.add(new Thumbnail(name, mobile));

接收下一个活动的列表

Intent intent = new Intent(getApplicationContext(),NewClass.class);
Bundle bundle = new Bundle();
bundle.putSerializable("values", adpter);
context.startActivity(intent);

答案 7 :(得分:0)

试试这种方式

public class MyAdapter extends Adapter {
     private Context context;

     public MyAdapter(Context context) {
      this.context = context;     
 }

 public View getView(...){
     View v;
     v.setOnClickListener(new OnClickListener() {
         void onClick() {
              Intent intent= new Intent(context, goto.class);
               intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
               intent.putextra("your_extra","your_class_value");
             context.startActivity(intent);
         }
     });
     }
}
相关问题