Search code examples
javaandroidandroid-asynctaskirc

Android: How to write data to scoket through AsyncTask


I am building an simple IRC-client for Android.

I using an AsyncTask to connect to Freenode/IRC-server.

I can easy get all the response from the irc-server,

An I can then show dialog base on the responses.

public class IrcTask extends AsyncTask<Void, String, Void> {
    public IrcTask(Activity activity, ProgressDialog pdialog, ScrollView sv_channel_output, List<String> join_users, BufferedWriter writer, BufferedReader reader, TextView outputView, String channel, String nick, String login) {
        this.activity = new WeakReference<Activity>(activity);//ChannelActivity
        this.nick = nick;
        this.login = login;
    }
    @Override
    protected Void doInBackground(Void... Sparams)  {
        // Connect directly to the IRC server.
        try {
            // Log on to the server.
            this.writer.get().write("NICK " + nick + "\r\n");
            this.writer.get().write("USER " + login + " 8 * : Freenode for Android App IRC Bot\r\n");
            this.writer.get().flush();

            // Join to the channel.
            this.writer.get().write("JOIN " + channel + "\r\n");
            this.writer.get().flush();

            // Read lines from the server until it tells us we have connected.
            String line = null;
            while ((line = this.reader.get().readLine( )) != null) {
                publishProgress(line);
                if (line.contains("PING ")) {
                    // We must respond to PINGs to avoid being disconnected.
                    this.writer.get().write("PONG " + line.substring(5) + "\r\n");
                    this.writer.get().flush( );
                }
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

On my ChannelActvity I has an EditView to send text/data to the server.

My problem is pass some write-data to the AsyncTask while it read from the server.

(After start the doInBackground->while.. just runs so it can send data back to my ChannelActicity)

I has try using 'SharedPreferences' to pass the write-data to the IrcServer.

But it do not work...

Like this...

// Read lines from the server until it tells us we have connected.
            String line = null;
            while ((line = this.reader.get().readLine( )) != null) {
                //gets/sets IRC-detils from 'MainActivity'
                pref = this.activity.get().getSharedPreferences("writeToIrcTack", 0);
                if(pref.getString("data", "").length() >0)
                {
                    Log.d("doInBackground->IF-it-gets-data", "pref.getString=="+pref.getString("data", ""));
                    this.writer.get().write("NOTICE "+channel+" " + pref.getString("data", "") + "\r\n");
                    this.writer.get().flush( );
                }
                publishProgress(line);

Solution

  • If you are using shared preferences from different activity/services/intents/... you should use it with mode MODE_MULTI_PROCESS (constant value int = 4). If not, file gets locked and only one process can write it at once!

    So when you call shared preferences in multi processes app do it like this:

    SharedPreferences preferences = this.getSharedPreferences("myapp",4);
    

    MODE_MULTI_PROCESS is ON on all version till android 2.3, but latter must be called strictly! Offical docs say:

    Operating mode. Use 0 or MODE_PRIVATE for the default operation, MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE to control permissions. The bit MODE_MULTI_PROCESS can also be used if multiple processes are mutating the same SharedPreferences file. MODE_MULTI_PROCESS is always on in apps targetting Gingerbread (Android 2.3) and below, and off by default in later versions.