简体   繁体   中英

Adding an item to a listview in an activity via external AsyncTask

Quick Question, i am looking to update a list view from an Async task in a different activity than the task was spawned from. My question is in regards updating the adapter in the other activity, how would i go about accessing the other activities adapter so i can add to it (using adapter.add(item);) and notify the adapter of change to update the list in the other activity (adapter.notifyChange();) ?

Here is connection task:

public class ConnectionTask extends AsyncTask<Context, String, Void> {

private String mText;
private Context mContext;
private int NOTIFICATION_ID = 1;
private Notification mNotification;
private NotificationManager mNotificationManager;




@SuppressWarnings("unused")
private NotificationActivity noteact = new NotificationActivity();


public ConnectionTask(Context context){

    this.mContext = context;

    //Get the notification manager
    mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);



}








@Override
protected void onPreExecute() {

    Log.i("PushNote", "onPreExecute");
}






public void setmText(String mText){
    this.mText = mText;
}


public String getmText(){
    return mText;
}


@Override
protected Void doInBackground(Context... params) {
    Socket clientSocket = null;
    //Creates the is connected boolean and sets it to false
    boolean connected = false;



    String ipaddr = getmText();

    // define a writer and a reader, so that we can interact with the
    // Server
    BufferedReader inFromServer = null;



    InetAddress addr = null;
    try {

        addr = InetAddress.getByName(ipaddr);
        } catch (UnknownHostException e1) {
        // TODO Auto-generated catch block
        publishProgress(e1.toString());
        e1.printStackTrace();
    }



    // Dynamically find IP of current Localhost
    String HostName = addr.getHostName();



    int port = 6789;


    try {
        // Lets try and instantiate our client and define a port number.


        clientSocket = new Socket(HostName, port);
        //  once the client is connected sets the isConnected boolean to true
        connected = true;



        // lets also link the writer and reader to the client.
        inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

        // make sure to always catch any exceptions that may occur.
        } catch (UnknownHostException e) {
        // always print error to "System.err"
        publishProgress(e.toString());
        // 2 different types of exceptions, so we want to output meaning
        // information for both.
        } catch (IOException e) {
        publishProgress(e.toString());
    }



    // Boolean which indicates if the client is connected or not,
    // if connected it takes in the next line of user input and returns the servers response.
    while (connected) {



        // Send the user message to the server




        // read the reply from the server
        String reply = null;
        try {
            reply = inFromServer.readLine();
            } catch (IOException e) {
            // TODO Auto-generated catch block

            e.printStackTrace();
            publishProgress("Failed to connect." );
            System.exit(1);

        }

        if (reply != null){

            // output the reply as a notification
            if (isCancelled()){
                break;
            }
            publishProgress(reply);


            } else {
            try {
                inFromServer.close();
                } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                publishProgress(e.toString());
                System.exit(1);
            } // the reader
            try {
                clientSocket.close();
                } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                publishProgress(e.toString());
                System.exit(1);
            } // and the client socket
        }

    }


    // always remember to close all connections.






    // TODO Auto-generated method stub
    return null;
}

@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
protected void onProgressUpdate(String... item) {

    Notification("Push2Note: ", item[0]);






}




public void Notification(String contentTitle, String contentText) {

    //Build the notification using Notification.Builder
    long[] vibrate = {0,100,200,300};

    PendingIntent pendingIntent;
    Intent intent = new Intent();
    intent.setClass(mContext,NotificationActivity.class);
    pendingIntent =  PendingIntent.getActivity(mContext, 0, intent, 0);


    NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext)
    .setSmallIcon(android.R.drawable.presence_online)
    .setAutoCancel(true)
    .setVibrate(vibrate)
    .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
    .setContentIntent(pendingIntent)
    .setContentTitle(contentTitle)
    .setContentText(contentText);

    //Get current notification
    mNotification = builder.getNotification();



    //Show the notification
    mNotificationManager.notify(NOTIFICATION_ID, mNotification);
}

}

Here is the activity im looking to populate:

public class NotificationActivity extends ListActivity {

    /** Called when the activity is first created. */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.notifications);

        setListAdapter(new ArrayAdapter(this,
                android.R.layout.simple_list_item_checked, new ArrayList()));

    }

}

Ive read trough similar questions and have heard tell of use of global adapters but have no idea how i can implement such a thing.

This is the last piece of the puzzle which remains a mystery to me with my applications and any help on the matter would be greatly appreciated.

Thanks for your time,

All the best.

You should have an ArrayList which the Adapter uses, that you can access from the Activity , which modifies it. It can be either public static or can be accessed via getter from the Activity which is passed as parameter to the Activity .

When you accessed the ArrayList , you can do whatever you want and then call invalidateViews() on the ListView for the other Activity .

items.remove(position);
MainListActivity.listView.invalidateViews();

Now, when your Adapter calls its getView() method, it gets the list which you updated.

一种方法是,将结果传递回活动,将它们添加到适配器列表并调用adapter.NotifyDatasetChanged();

Ok well the answer was simpler than i thought it would be instead of adding to the array list in the async task i created an empty array list in the activity and then added to the adapter. This does however mean that the activity must be active before the AsyncTask is run (otherwise you try to add to an non-existent adapter) but for my purposes thats just fine. The code:

in ConnectionTask i passed the value to publishprogress and then executed

NotificationActivity.adapter.add(item[0]);

and then in my Activity i now have:

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

ArrayList<String> mArrayList = new ArrayList<String>();

adapter = new ArrayAdapter<String>(this, R.layout.recentrow,mArrayList);


setListAdapter(adapter);


ListView listView = getListView();
listView.setTextFilterEnabled(true);


}   

Thanks for all the help guys, couldn't have gotten here without you making me rethink things.

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